Modules are defined using a modulemd file. The definition includes the summary and description, list of source RPM packages, build information i.e. buildroot, and usage information i.e. installation profiles or licenses.

This page will help you with writing a module definition from scratch. Even though this page is meant to be up-to-date, please make sure your module complies with the Fedora Packaging Guidelines for Modules as it is the authoritative point of truth.

Common definitions

Every modulemd starts with these three lines:

document: modulemd
version: 2
data:
    ... (1)
1 All the following definitions go here, under data.

Information about your module

Tell users what this module represents by writing a summary and a description, and how can they use it by specifying a license.

    summary: An example module
    description: >-  (1)
        A module for the demonstration of the metadata format. Also,
        the obligatory lorem ipsum dolor sit amet goes right here.
    license:
        module:
            - MIT  (2)
1 The >- means new line in YAML. Useful for longer blocks of text, such as the description!
2 A license for this modulemd file. Fedora content, such as SPEC files or patches not included upstream, uses the MIT license by default, unless the component packager declares otherwise.

List the packages

To make your module useful, include some RPM packages in it. List all source RPM packages this module should include.

    components:
        rpms:
            first-package:  (1)
                rationale: Provides the core functionality.  (2)
                ref: 3.0  (3)
            second-package:
                rationale: Web UI for the first-package.
                ref: stable
            ...  (4)
1 Name of the package — maps to a DistGit repository name.
2 The reason why is this package here. Mostly for humans.
3 DistGit branch, tag, or a commit — so the right version of the package gets included.
4 List as many packages as you need.

For which releases?

To build your module for all Fedora releases that are actively maintained, use the following definition. For anything more than this, such as building against other modules or requiring other modules during runtime, please see the Advanced section below.

    dependencies:
      - buildrequires:
            platform: []
        requires:
            platform: []

Help users install it (optional, but encouraged)

To help users install your module, define installation profiles. These profiles represent a specific use case of your module. Most modules have at least a default profile. But you can specify more. For example, a database module can have a server and a client profile.

    profiles:
        default:  (1)
            description: A standard installation.  (2)
            rpms:
                - package-one         (3)
                - package-one-extras  (3)
                - package-two         (3)
        cli:
            description: A command-line client.
            rpms:
                - package-one-cli
        ...  (4)
1 Name of the profile.
2 A quick summary of the profile.
3 Binary packages to be installed with this profile.
4 List as many profiles as you need.

Public API (optional, but encouraged)

List all binary RPM packages in your module that you consider to be the main stable feature of the module. Other (unlisted) packages should be considered unsupported, or an implementation detail.

    api:
        rpms:
            - package-one
            - package-one-extras
            - package-one-cli
            - package-one-devel
            - package-two

Advanced definitions

References to the upstream (optional)

You can also provide references to the upstream community, documentation, or to an issue tracker.

    references:
        community: http://www.example.com/  (1)
        documentation: http://www.example.com/  (2)
        tracker: http://www.example.com/  (3)
1 Upstream community website, if it exists.
2 Upstream documentation, if it exists.
3 Upstream bug tracker, if it exists.

Building in a specific order (optional)

Packages are built in batches. By default, all packages are part of a single group, and therefore built concurently.

To build packages in a specific order, assign them to multiple build groups. Build groups are identified by an integer. Groups with lower number are built first. Negative values are allowed, 0 is the implicit default value.

In this specific example, first-package gets built first, and second-package gets built second.

    components:
        rpms:
            first-package:
                rationale: Provides the core functionality.
                ref: 3.0
                buildorder: 0  (1)
            second-package:
                rationale: Web UI for the first-package.
                ref: stable
                buildorder: 10  (1)
1 A number of the build group.

Build macros (optional)

Use this if you need to build your packages with a specific RPM macro. Applies to all packages in the module.

    buildopts:
        rpms:
            macros: |
                %demomacro 1
                %demomacro2 %{demomacro}23

Advanced dependencies (optional)

modules can be

  • built against other modules

  • require other modules during runtime

  • built agains one or more streams of the same module

  • work with one or more streams of another module

Building for a specific Fedora release(s) only

Building only for Fedora 28:

    dependencies:
      - buildrequires:
            platform: [f28]
        requires:
            platform: [f28]

Building for everything else than Fedora 28:

    dependencies:
      - buildrequires:
            platform: [-f28]
        requires:
            platform: [-f28]

Building only for Fedora 28 and Fedora 29:

    dependencies:
      - buildrequires:
            platform: [f28, f29]
        requires:
            platform: [f28, f29]

Depending on other modules

Your module can also depend on another modules. Specific streams can be referenced the same way as above in "Building for a specific Fedora release(s) only".

    dependencies:
      - buildrequires:
            platform: []
            nodejs: []
        requires:
            platform: []
            nodejs: []

Complex dependencies

Simple things should simple, complex things should be possible. Let’s say my module requires nodejs during build and run time. It also requires build-tools only during build. To make it even more complex, it also requires a specific stream of a pizza-module during build and run time, but only on Fedora 27.

    dependencies:
      - buildrequires:
            platform: [-f27]
            buildtools: [v1, v2]
            nodejs: []
        requires:
            platform: [-f27]
            nodejs: []
      - buildrequires:
            platform: [f27]
            buildtools: [v1, v2]
            nodejs: []
            pizza-module: [3.6]
        requires:
            platform: [f27]
            nodejs: []
            pizza-module: [3.6]

For even more complex scenarios, please study the modulemd specification.

Binary packages to exclude (optional)

One source RPM package might produce multiple binary RPM packages. If you don’t want to include some binary packages, list them under filter.

    filter:
        rpms:
            - first-package-debuginfo
            - second-package-nope

A minimal modulemd

An absolute minimum

This module includes two source RPM packages built for all Fedora releases.

document: modulemd
version: 2
data:
    summary: An example module
    description: >-
        A module for the demonstration of the metadata format. Also,
        the obligatory lorem ipsum dolor sit amet goes right here.
    license:
        module:
            - MIT
    dependencies:
      - buildrequires:
            platform: []
        requires:
            platform: []
    components:
        rpms:
            first-package:
                rationale: Provides the core functionality.
                ref: 3.0
            second-package:
                rationale: Web UI for the first-package.
                ref: stable

This module includes two source RPM packages built for all Fedora releases. It makes clear which packages are considered the API, and helps users with installation thanks to the profiles.

document: modulemd
version: 2
data:
    summary: An example module
    description: >-
        A module for the demonstration of the metadata format. Also,
        the obligatory lorem ipsum dolor sit amet goes right here.
    license:
        module:
            - MIT
    dependencies:
      - buildrequires:
            platform: []
        requires:
            platform: []
    api:
        rpms:
            - package-one
            - package-one-extras
            - package-one-cli
            - package-one-devel
            - package-two
    profiles:
        default:
            description: A standard installation.
            rpms:
                - package-one
                - package-one-extras
                - package-two
        cli:
            description: A command-line client.
            rpms:
                - package-one-cli
    components:
        rpms:
            first-package:
                rationale: Provides the core functionality.
                ref: 3.0
            second-package:
                rationale: Web UI for the first-package.
                ref: stable

Bonus: Converting modulemd v1 to v2

This video walks through the differences between the legacy modulemd v1 and the current modulemd v2.