# File format

To configure your project via a user-friendly form, you'll need to create a new file at the same location as your .cycloid.yml file; this one is called .forms.yml

The .forms.yml file allows the creation (or update) of a project via a nice interface. It allows for an easier and more controlled configuration of stacks: restrict the values provided, variables exposed, range, etc.

The overall structure layout can be represented via this definition:

version: "2"
use_cases:
- name: use-case-N
  sections:
  - name: section-A
    groups:
    - name: group-1
      technologies: [terraform]
      vars:
        # vars definition here
  [...]
1
2
3
4
5
6
7
8
9
10
11

For an extended list of examples, please see the examples section directly.

# Use-case, Section & Group definition

The structure must respect the following:

  • use-case: it must match the .cycloid.yml file use-cases definition.
  • section: these are just logical grouping entities, that allows to more easily split the variable and understanding of the configuration
  • group: these serve two purposes - logical grouping entities, and configuration that will apply to variables of the group (see explanation below)
  • var-definition: please see the next section for an extended description of the format

As previously mentioned the use-case should match the one from the .cycloid.yml file, if a use-case present in the stack file isn't present in the .forms.yml one, you won't be able to configure it and you'll have to use the legacy interface instead for that use-case.

The sections and groups allow you to split your configuration into logical categories, you are free to pick any name for those. You could for example have a section dedicated to your Application, and then groups specific for each service: Cache settings, Versions to use, Database parameters, etc.

However, group's definition not only contains the list of variables but also the technologies for which this configuration applies. For more deatils, please see the sharing of technologies section.

# Attribute definition

Attribute definition includes many more fields, not all of which are mandatory or have the same constraints.

Attribute Type Required Description
key string yes key is the name of the attribute located in the sample files from .cycloid.yml file. See notes about key attribute
name string yes name of the attribute displayed to the user
type string yes the type of data handled
widget string yes the widget used to display the data in the most suitable way
default any no the default value to assign to the attribute if nothing is set by the user (used when required). Matches the type
description string no description helping users understand the interest/impact of such variable/change. This supports markdown format (opens new window), so you can easily insert bold, italic or links into the description of your varaible.
required boolean no whether or not the attribute is required
source string no source is only used for the branch widget, see the section for more details
unit string no unit to be displayed for the attribute, helping to know what's being manipulated amount of servers, storage in Go, users, etc
values any no list of allowed values, please check the possible types
values_ref string no URL to a remote location that will return a JSON that will be used as values, can be used anywhere values is used

Here is an exmaple on how you could use markdown in your descriptions:

info

The default attribute for cy_cred widget might have a different format depending of the technology

  • ansible: cred_path/field
  • pipeline: ((cred_path.field))

# Key attribute

The key format to respect for ansible and pipelines is: keyX, where keyX is the name of the variable you want to replace. Basically Cycloid will look for variables present in your samples, for each technology that has variables matching the keys that you've given.

For Terraform however, there are 2 ways to use a key:

  1. the "short" way (identical to ansible/pipeline): keyX. This works for every module existing which have such key.
  2. the "long" one module.Y.keyX for terraform. Works for setting up the specific variable of a module.

Warning

In the previous version of the forms, the "short" version would work only with one module, while the long one would still be for a specific one.

Example:

If you create a variable with the key servers this will be applied to both "frontend" & "backend" modules. While if you wanted to modify only the "frontend" servers, then you'd have to specify the key module.frontend.servers.

module "frontend" {
  source = "./app-cluster"
  servers = 5
}

module "backend" {
  source = "./app-cluster"
  servers = 5
}
1
2
3
4
5
6
7
8
9

# Type attribute

The type constraints will ensure that the data provided matches the expected type. If you passed a string instead of a number, an error would be triggered.

The same applies if you set a default or values that do not respect the type.

The list of supported types:

  • integer: an integer number
  • float: a float number
  • string: any type of string
  • array: any type of array (number, string, etc)
  • boolean: true or false
  • map: any type of map
  • raw: any content which is valid YAML/HCL depending on technologies

The map type can be displayed as JSON but is properly converted to/from YAML/HCL when stored and retrieved.

The raw type is meant to be used for data that is too complex to be represented easily with the other type. It will be written to the files directly as such, but still has to be valid YAML (for pipelines/ansible technology) or valid HCL (for terraform).

# Map attribute & mapped values

It can happen that when using the form, you'd want to rather display some text instead of a specific value which might not be very obvious to users. e.g: L instead of m5.large To achieve this, you'd need to use the map type, with values & defaults formatted differently, as they would need to include label (the text displayed) and value (the associated value) fields. See the table of Widget/Type & Values constraints to know which widget allows you to use it.

For example, let say that you wanted to use various instance flavors for your users to pick from, you could do:

This way the user would only see "simple" and more understandable names, instead of some more technical terms which can be confusing to pick from.

# Widget attribute

The widgets are meant to provide easy configuration for the most common type of data. Some extras have been added to cover some elements used in Cycloid.

Widget Render
auto_complete ac
Provides suggestions while you type into the field
cy_cred cred
Expose cycloid credentials available
cy_scs scs
Expose cycloid catalog repositories available
cy_crs crs
Expose cycloid config repositories available
cy_branch branch
Expose branches available from cy_scs or cy_crs
dropdown dd
Menus display a list of options
number n
Simple field dedicated to numbers
radios r
Graphical control element that allows the user to choose only one of a exclusive options
simple_text st
Simple field dedicated to text
slider_list sl
Select option by dragging a slider along list of options
slider_range sr
Select option by dragging a slider along a range
switch ta
Choosing between 2 positions on/off
text_area ta
Multi-line text field

As you might have noticed, a couple of those widgets are "special". By special, we mean that they aim to simplify using Cycloid entities. In our case: credentials, service catalog, config repositories, and/or branches. To help identify them, we have prefixed them with cy_.

The cy_branch is the only one that uses the variable source because to be able to select it, we need to know which repository to request. This is why the source must reference a valid key that belongs to either a cy_scs or cy_crs variable. If this isn't the case, an error will be triggered.

# Widget/Type & Values constraints

Due to the nature of widgets, there are limitations applied to the types & values accepted. Here is a summary of all supported couples:

Widget Type Values
auto_complete string Needs at least 2 values, which are hints rather than restrictions
cy_cred string
cy_scs string
cy_crs string
cy_branch string
dropdown any but raw At least 1 values, if Boolean only 2 allowed
number integer, float
radios any but raw At least 1 values, if Boolean only 2 allowed
simple_text string
slider_list string, boolean, integer, map At least 1 values, if Boolean only 2 allowed
slider_range integer Only 2 values accepted, mininimal value first then maximum
switch boolean Does not take any values
text_area any

# Default attribute

Default value is the one that will be automatically selected when creating the project for the first time. Once it has been created, if you were to edit it then the value selected would be the one you previously picked.

# Default raw type case

Variables of raw type are considered strings to avoid YAML or HCL formatting.

Thus if you want to specify raw complex (multi-line array, map, etc) default values, you have to use a YAML formatter to avoid modifications too. YAML has several multi-line formatter (>, >+, |, |-, etc), the ones that we advise using is: |+.

This is because the formatter |+ will write exactly the string as it is given, which fits best with the concept of raw variable.

Some others could also work, but you have to be careful with the one you use, as it could slightly change the output of the given variable. | if you want to trim extra unnecessary new lines at the end. If you leave 3, they will be replaced by one. |- would strip any new lines at the end.

More info on: https://yaml-multiline.info/ (opens new window)

Example:

  - name: "Ansible params raw"
    description: "Parameters of ansible-runner script (raw). Can be found here: https://github.com/cycloidio/cycloid-images/tree/master/cycloid-toolkit#ansible-runner"
    key: ansible_params_raw
    widget: text_area
    type: raw
    default: |+
      SSH_JUMP_URL: user1@Bastion1
      SSH_PRIVATE_KEYS:
        - ((ssh_bastion.ssh_key))
      ANSIBLE_VAULT_PASSWORD: ((raw_ansible_password))
      ANSIBLE_PLAYBOOK_PATH: ansible-playbook/
      ANSIBLE_PLAYBOOK_NAME: playbook.yml
      EXTRA_ANSIBLE_VARS:
        customer: ($ organization_canonical $)
        project: ($ project $)
        env: ($ environment $)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16