the anatomy of a frecklet

example: creating a user

To understand the anatomy of a frecklet, let’s have a look at a full-blown one that is actually used (and included in the frecklet package). This one let’s you ensures that user exists on a host machine (as well as their optional group). It also gives the option to specify the UID and whether the user is supposed to be a system user or not:

doc:
  short_help: ensures a user exists on a system

args:
  name:
    doc:
      short_help: the name of the user
    type: string
    required: true
    cli:
      metavar: USER_NAME
      param_type: argument
  group:
    doc:
      short_help: the name of the users main group
    type: string
    required: false
    cli:
      metavar: GROUP_NAME
  uid:
    doc:
      short_help: the uid of the user
    type: integer
    required: false
    cli:
      metavar: UID
  system:
    doc:
      short_help: whether this user should be created as system user
    type: boolean
    required: false
    cli:
      show_default: true
      is_flag: true

tasks:
  - ensure-group-exists:
      task.__skip__: "{{:: group | true_if_string_doesnt_exist ::}}"
      group: "{{:: group ::}}"
      system: "{{:: system | default(omit) ::}}"
  - task:
      command: user
      type: ansible-module
      __msg__: "[creating user if it doesn't exist yet: {{:: name ::}}]"
      become: true
    vars:
      name: "{{:: name ::}}"
      state: present
      uid: "{{:: uid | default(omit) ::}}"
      system: "{{:: system | default(omit) ::}}"

This is what freckletcute tells us about it:

$ frecklecute ensure-user-exists --help
Usage: frecklecute ensure-user-exists [OPTIONS] USER_NAME

  ensures a user exists on a system

Options:
  --gid GID           the gid of the optional group
  --group GROUP_NAME  the name of the users main group
  --system            whether this user should be created as
                      system user  [default: False]
  --uid UID           the uid of the user
  --help              Show this message and exit.

Let’s have a look at the sections this file:

documentation: doc

The doc section houses the general documentation about a frecklet. What it does, how it does it (if applicable). This section is optional, but it is highly recommended to have one in a frecklet, esp. if you plan to share it with other people. But also as record for yourself in 6 months…

doc:
  short_help: ensures a user exists on a system

The main two keys of this section are called help and short_help. The short_help value string is used as text to display for example when calling frecklecute --help. The help value is a string in markdown format, and it’s used when calling --help on the specific frecklet (see example above).

Note the format of the help key:

help: |
  Ensure a ...

  Optionally ..

This is using the YAML multiline block format, if you are familiar with YAML you can also use other supported ways of specifying multi-line strings.

documentation: args

This

args:
  name:
    doc:
      short_help: the name of the user
    type: string
    required: true
    cli:
      metavar: USER_NAME
      param_type: argument
  group:
    doc:
      short_help: the name of the users main group
    type: string
    required: false
    cli:
      metavar: GROUP_NAME
  uid:
    doc:
      short_help: the uid of the user
    type: integer
    required: false
    cli:
      metavar: UID
  system:
    doc:
      short_help: whether this user should be created as system user
    type: boolean
    required: false
    cli:
      show_default: true
      is_flag: true

documentation: tasks

tasks:
- ensure-group-exists:
    task.__skip__: '{{:: group | true_if_string_doesnt_exist ::}}'
    group: '{{:: group ::}}'
    system: '{{:: system | default(omit) ::}}'
- task:
    command: user
    type: ansible-module
    __msg__: "[creating user if it doesn't exist yet: {{:: name ::}}]"
    become: true
  vars:
    name: '{{:: name ::}}'
    state: present
    uid: '{{:: uid | default(omit) ::}}'
    system: '{{:: system | default(omit) ::}}'

full schema

Here’s the basic schema for frecklets:

args:
  type: dict
  schema:
    type: string
doc:
  type: dict
  schema:
    short_help:
      type: string
meta:
  type: dict
tasks:
  type: list
  schema:
    type: dict
    schema:
      task:
        type: dict
      vars:
        type: dict

Under the hood, freckles is using the brilliant Cerberus library. Check out its documentation whenever you come across a schema in freckles.