Skip to content

docs: refresh K8s tutorial to use Concierge and uv-based Charmcraft profile#2285

Merged
dwilding merged 19 commits intomainfrom
k8s-tutorial-uv
Jan 29, 2026
Merged

docs: refresh K8s tutorial to use Concierge and uv-based Charmcraft profile#2285
dwilding merged 19 commits intomainfrom
k8s-tutorial-uv

Conversation

@dwilding
Copy link
Copy Markdown
Contributor

@dwilding dwilding commented Jan 23, 2026

This PR makes significant changes to our Kubernetes charm tutorial.

Main changes

  • Use similar environment setup instructions as our machine charm tutorial. The instructions explain how to use Concierge to prepare a Multipass VM with Canonical Kubernetes and charm dev tools. I'm recommending that the reader mounts a local directory into their VM so that they can use their IDE to edit charm code. Preview chapter

    I also made a small clarification to the setup instructions of the machine charm tutorial.

  • Start the charm from the latest Charmcraft kubernetes profile. This removes the need for the reader to create several files, including charmcraft.yaml, pyproject.toml, and tox.ini. The charm expects uv for managing dependencies and uses Charmcraft's uv plugin. Preview chapter

  • Manually find transitive dependencies of Charmhub-hosted libs. This makes the last chapter slightly more complicated, but is unavoidable because the observability libs haven't been migrated to charmlibs packages and Charmcraft's uv plugin doesn't extract PYDEPS from libs. Preview section

These changes were reviewed in my intermediate PRs #2258, #2259, and #2281.

Unrelated changes

  • Mention that Charmcraft might show a warning when fetching libs.

  • I fixed a bug in the demo server workload. Version 1.0.1 of the image returns version string 1.0.0 from the API. I'm switching the tutorial to use version 1.0.2 of the image, which correctly returns version string 1.0.2.

Adjustments after testing

After the main changes had been reviewed, I tested the tutorial from end to end and made some small adjustments/fixes: f33ac24, 2851e1f, 71b9838, f8b22a8.

Further adjustments during PR review: 7d36dce

Final adjustments to add a note about issues accessing services inside the VM: 837df1b

This is an **intermediate PR** for switching the [Kubernetes charm
tutorial](https://documentation.ubuntu.com/ops/latest/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/)
to use uv and the latest Charmcraft profiles. Target branch is
`k8s-tutorial-uv`

---

This PR copies the [environment setup
instructions](https://documentation.ubuntu.com/ops/latest/tutorial/write-your-first-machine-charm/#set-up-your-environment)
and adapts them for Canonical Kubernetes instead of LXD.

**[Preview
doc](https://canonical-ubuntu-documentation-library--2258.com.readthedocs.build/ops/2258/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/set-up-your-development-environment/)**

I'm calling the VM `juju-sandbox-k8s` instead of `juju-sandbox` to make
it easier for people to complete both tutorials.

I'm making one drive-by update to the machine charm tutorial (see
comment).
This is an **intermediate PR** for switching the [Kubernetes charm
tutorial](https://documentation.ubuntu.com/ops/latest/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/)
to use uv and the latest Charmcraft profiles. Target branch is
`k8s-tutorial-uv`

---

This PR switches "Create a minimal Kubernetes charm" to use a charm
project generated by the latest version of Charmcraft. That lets us
remove several of the manual steps.

**[Preview
doc](https://canonical-ubuntu-documentation-library--2259.com.readthedocs.build/ops/2259/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/create-a-minimal-kubernetes-charm/)**

I'm fully updating "Create a minimal Kubernetes charm" and the
corresponding example charm. I'm also partially updating subsequent
chapters, for consistency of naming, but I'm not updating the subsequent
example charms yet. I'll fully update the subsequent chapters and
example charms in follow-on PRs.

There's some noise in the PR due to:
- Switching the charm name from `demo-api-charm` to `fastapi-demo`
- Switching from single to double quoted code (matching our other
example charms)

In `examples/k8s-minimal-1`, the charm code in `charm.py` and the unit &
integration tests are essentially the same as before. Other charm files
match what comes from Charmcraft. (`charmcraft.yaml` comes with a
placeholder config option, which we'll replace in a later chapter of the
tutorial, in a subsequent PR.)

So I think the most important part to review is
`create-a-minimal-kubernetes-charm.md`.
This is an **intermediate PR** for switching the [Kubernetes charm
tutorial](https://documentation.ubuntu.com/ops/latest/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/)
to use uv and the latest Charmcraft profiles. Target branch is
`k8s-tutorial-uv`

---

This PR modifies "Make your charm configurable" to replace the `config`
block in `charmcraft.yaml` instead of adding the block.

The latest Charmcraft profile already has a placeholder `config` block.
In `k8s-1-minimal`:

```yaml
# (Optional) Configuration options for the charm
# This config section defines charm config options, and populates the Configure
# tab on Charmhub.
# More information on this section at:
# https://documentation.ubuntu.com/charmcraft/stable/reference/files/charmcraft-yaml-file/#config
# General configuration documentation:
# https://documentation.ubuntu.com/juju/3.6/reference/configuration/#application-configuration
config:
  options:
    # An example config option to customise the log level of the workload
    log-level:
      description: |
        Configures the log level of gunicorn.

        Acceptable values are: "info", "debug", "warning", "error" and "critical"
      default: "info"
      type: string
```

After replacing the `config` block, per the updated doc, the block in
`k8s-2-configurable` is:

```yaml
config:
  options:
    server-port:
      default: 8000
      description: Default port on which FastAPI is available
      type: int
```

**[Preview of updated
doc](https://canonical-ubuntu-documentation-library--2279.com.readthedocs.build/ops/2279/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/make-your-charm-configurable/#define-the-configuration-option)**

This PR only touches the doc. I've already updated `k8s-2-configurable`
to match the charm structure in `k8s-1-minimal`.
This is an **intermediate PR** for switching the [Kubernetes charm
tutorial](https://documentation.ubuntu.com/ops/latest/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/)
to use uv and the latest Charmcraft profiles. Target branch is
`k8s-tutorial-uv`

---

This PR:

- Updates [Integrate your charm with PostgreSQL
(preview)](https://canonical-ubuntu-documentation-library--2281.com.readthedocs.build/ops/2281/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/integrate-your-charm-with-postgresql/#fetch-the-required-database-interface-charm-library)
to explain that Charmcraft might show a warning when fetching libs -
thanks @xdqi for raising this! I'm also improving the guidance about
setting `PYTHONPATH`.
- In [Observe your charm with COS Lite
(preview)](https://canonical-ubuntu-documentation-library--2281.com.readthedocs.build/ops/2281/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/observe-your-charm-with-cos-lite/):
- Adds a section "Add dependencies from libraries" about including
`cosl` as a dependency.
- Removes an incorrect note about Charmcraft copying the contents of
`lib`. As explained in the PostgreSQL chapter, what actually happens is
that the `dispatch` script sets `PYTHONPATH`. The note also mentioned
how to import a lib, which isn't necessary because the chapter covers
that later.
- Removes the binary package workaround that was needed when we used the
Charm plugin.
    - Mentions the same Charmcraft warning as in the PostgreSQL chapter.
- Adds `cosl` as a dependency of the relevant charm code.
- Updates our "Example Charm Integration Tests" workflow so that it
correctly handles uv-based charms that use Charmhub-hosted libs.

The workflow doesn't run on PRs, so I temporarily enabled it here and
checked that it succeeded:
https://github.com/canonical/operator/actions/runs/21170536298/
@dwilding dwilding linked an issue Jan 23, 2026 that may be closed by this pull request
@dwilding dwilding changed the title docs: refresh K8s tutorial to use Concierge and uv-based Charmcraft profiles docs: refresh K8s tutorial to use Concierge and uv-based Charmcraft profile Jan 23, 2026
@dwilding dwilding requested a review from Copilot January 23, 2026 01:42

This comment was marked as outdated.

@dwilding dwilding marked this pull request as ready for review January 27, 2026 09:43
Copilot AI review requested due to automatic review settings January 27, 2026 09:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 54 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/k8s-5-observe/charmcraft.yaml
@dwilding
Copy link
Copy Markdown
Contributor Author

Connecting to the Grafana dashboard outside the VM doesn't seem to be working with Canonical Kubernetes - at least as far as I can tell. This is the very last part of the tutorial. I'm investigating why. Per internal discussion today, we'd prefer to stick with Canonical Kubernetes if possible.

In the meantime, @tonyandrewmeyer & @james-garner-canonical would you mind reviewing the rest? Most changes have been reviewed by at least one person already - see the description for a summary of what's been reviewed and what's new since review (some small adjustments). Very much appreciated!

Copy link
Copy Markdown
Collaborator

@tonyandrewmeyer tonyandrewmeyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great PR description, thanks! Very clear on what's been done, what's had some review, and what the focus here should be.

It's unfortunate that there's so much noise from the duplication and particularly the quote style switch. Hopefully, we don't need to do something like this again for a while!

I haven't run through the tutorial myself for the review, only read the raw and preview versions. I'm happy to trust that you've done it and that another run-through isn't going to provide value.

The set up chapter is much nicer now. I like how much we've been able to cut from the crest chapter, too.

As a drive-by, what do you think about dropping the phrase "As you already know from your knowledge of Juju, "?

Overall, looks great - thanks for all the work on this! A couple of comments, but good to merge from my perspective.

Comment thread examples/k8s-5-observe/pyproject.toml
Comment thread examples/k8s-2-configurable/charmcraft.yaml
Copy link
Copy Markdown
Contributor

@james-garner-canonical james-garner-canonical left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes look great, David, thanks. And thanks for the helpful PR description.

I also haven't actually run through the tutorial. I believe one of the current onboarders is just about to do this module, so perhaps we can ask them for extra feedback.

@dwilding
Copy link
Copy Markdown
Contributor Author

Thank you very much for the reviews. I've addressed the feedback and will merge now.

I'm working on a separate PR that will improve the instructions for how to connect to Grafana from outside the VM. Instead of using ip route add to forward traffic, we can connect directly to the Traefik load balancer's Kubernetes service. AFAIU, this is more in the spirit of how COS Lite is designed to work. It also has the benefit of being cross-platform.

Until that improvement is ready, I've added this note to the last chapter:

There is currently an issue with this part of the tutorial. If you follow the instructions, you may not be able to access Grafana from your host machine. We’re working on improving the instructions. Check back soon for the new instructions!

@dwilding dwilding merged commit 51cdf22 into main Jan 29, 2026
62 checks passed
@dwilding dwilding deleted the k8s-tutorial-uv branch January 29, 2026 09:23
dwilding added a commit that referenced this pull request Feb 5, 2026
This PR reworks the final part of our Kubernetes charm tutorial - the
part that explains how to inspect metrics and logs from the application
(after deploying & integrating COS Lite).

Main changes:

- Replaced the instructions for accessing the Grafana web UI outside the
VM. Instead of asking the reader to do `sudo ip route add ...` on their
host machine and connect to the Grafana service, I'm showing them how to
connect to Grafana through the ingress that COS Lite manages. This
approach is much closer to how a production setup would work, fixes an
issue that appeared after we switched to Canonical K8s (in
[#2285](#2285)), and is
supported cross platform.

- Fixed the Grafana dashboard to display logs. At some point, the label
that the Loki charm sets (when Pebble is forwarding workload logs) was
changed from `juju_charm` to `charm`, which broke our dashboard.

- Added instructions for how to send continuous requests to the
workload. This makes the Grafana dashboard easier to understand, as
there are graphs instead of a couple of isolated points.

- Tidied up the Grafana dashboard. E.g., there's no need to show four
different duration percentiles - that just makes it harder to understand
what's going on. I also tidied up the descriptions of what the dashboard
shows.

- Promoted the note about viewing metrics in Prometheus. It's now a
short section that includes an sample query and a screenshot of the
results.

**[Preview
doc](https://canonical-ubuntu-documentation-library--2305.com.readthedocs.build/ops/2305/tutorial/from-zero-to-hero-write-your-first-kubernetes-charm/observe-your-charm-with-cos-lite/#simulate-api-requests)
- Start reading from "Simulate API requests"**
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update K8s tutorial to start with charmcraft init

4 participants