App Parameters

Introduction

When working with applications composed of multiple blocks, managing common parameters across all blocks can become cumbersome. Consider an application that consists of six blocks. Each block needs to connect to a database and query multiple tables. However, these tables have suffixes that depend on whether we are accessing beta data or production data. To keep the application generic, we pass the suffix as a build parameter to all the blocks.

In the current setup, when deploying the app, we have to pass the same parameter individually to each block. If there are ten such parameters, we need to provide values for all ten in the six different blocks. Additionally, if we have run parameters that need updating, we must update the parameters in all the blocks separately.

This leads us to ask:

Is there a better way to pass values to these common parameters?

The answer is yes. That’s where App Parameters come into play.

What are App Parameters?

App Parameters are parameters—both build and run—that are defined at the app level and inherited by block parameters. To define a parameter at the app level, it must already be defined in at least one of the blocks belonging to the app.

When creating an app deployment, we can provide values to the app parameters. The parameter value will automatically be utilized by any block that has the same parameter defined in its spec. We can also provide the parameter value at the block level, which will override the one defined at the app level for that specific block.

Using App Parameters

Before we delve into defining parameters in the app spec, let’s first create a couple of block specs.

Block Specs

Below are the configuration files for two example blocks. Each block defines a set of parameters, which include both build parameters (passed during deployment) and run parameters (used at runtime).

Block Spec 1

The first block spec defines two build parameters:

  • table_prefix: A prefix to specify the starting identifier for table names.

  • table_suffix: A suffix to specify the ending identifier for table names.

Additionally, it includes one run parameter:

  • table: The specific table name to be queried.

# block-1.yml

body:
    version: 1
    kind: workflow
    metadata:
        name: block-1
        title: BLOCK 1
        summary: BLOCK 1
        description: BLOCK 1
        descriptionContentType: text/markdown
        imageUrl: https://cdn-icons-png.flaticon.com/512/5698/5698690.png
        tags:
            - name: cli
    release:
        version: 1.0.0
        notes: This is the original release
    config:
        steps:
            step-1:
                command: python main.py
                type: standard
                image:
                    dockerfile: Dockerfile
                    buildArguments:
                        TABLE_PREFIX: "@param:table_prefix"
                        TABLE_SUFFIX: "@param:table_suffix"
parameters:
    build:
        - name: table_prefix
          type: string
          required: false
          description: The Prefix to be used in table names
          defaultValue: ""
        - name: table_suffix
          type: string
          required: false
          description: The Suffix to be used in table names
          defaultValue: ""
    run:
        - name: table
          type: object
          required: true
          properties:
              - name: name
                type: string
                required: true
                description: name of the table
              - name: primary_key
                type: string_array
                required: true
                description: Primary key of the table
              - name: columns
                type: object_array
                required: true
                description: Columns of the table
                properties:
                    - name: name
                      type: string
                      required: true
                      description: name of the column
                    - name: type
                      type: string
                      required: true
                      description: type of the column
                    - name: nullable
                      type: boolean
                      required: true
                      description: nullable of the column
                    - name: default
                      type: string
                      required: false
                      description: default value of the column
artifact:
    path: image

Block Spec 2

The second block configuration is similar to the first but includes an additional build parameter:

  • dev_env_id: An identifier for the development environment, allowing the block to dynamically switch based on the environment.

This block also includes the table_prefix, table_suffix, and table parameters from the first block.

# block-2.yml

body:
    version: 1
    kind: workflow
    metadata:
        name: block-2
        title: BLOCK 2
        summary: BLOCK 2
        description: BLOCK 2
        descriptionContentType: text/markdown
        imageUrl: https://cdn-icons-png.flaticon.com/512/5698/5698690.png
        tags:
            - name: cli
    release:
        version: 1.0.0
        notes: This is the original release
    config:
        steps:
            step-1:
                command: python forecast.py
                type: standard
                image:
                    dockerfile: Dockerfile
                    buildArguments:
                        TABLE_PREFIX: "@param:table_prefix"
                        TABLE_SUFFIX: "@param:table_suffix"
                        DEV_ENV_ID: "@param:dev_env_id"
parameters:
    build:
        - name: table_prefix
          type: string
          required: true
          description: The Prefix to be used in table names
          defaultValue: ""
        - name: table_suffix
          type: string
          required: true
          description: The Suffix to be used in table names
          defaultValue: ""
        - name: dev_env_id
          type: string
          required: false
          description: The Dev Env ID
          defaultValue: ""
        - name:
    run:
        - name: table
          type: object
          required: true
          properties:
              - name: name
                type: string
                required: true
                description: name of the table
              - name: primary_key
                type: string_array
                required: true
                description: Primary key of the table
              - name: columns
                type: object_array
                required: true
                description: Columns of the table
                properties:
                    - name: name
                      type: string
                      required: true
                      description: name of the column
                    - name: type
                      type: string
                      required: true
                      description: type of the column
                    - name: nullable
                      type: boolean
                      required: true
                      description: nullable of the column
                    - name: default
                      type: string
                      required: false
                      description: default value of the column
artifact:
    path: image

Creating the Block Specs

  • Remember that both blocks need a Dockerfile located in a folder called image. Be sure to create this folder and add the Dockerfile before creating the blocks.

  • You can create the blocks using the following commands:

    peak blocks specs create block-1.yml
    peak blocks specs create block-2.yml
    

Creating the App Spec

  • Notice that the two blocks have three parameters in common: two build parameters (table_prefix and table_suffix) and one run parameter (table).

  • These parameters are ideal candidates to be defined as app parameters, allowing us to specify their values only once during deployment. Here’s how we can do it:

    # app-spec.yml
    
    body:
        version: 1
        kind: app
        metadata:
            name: app-spec
            title: App Spec
            summary: App Spec
            description: |
                # App Spec
            descriptionContentType: text/markdown
            imageUrl: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRCKlDqjmjeUXeriZ7G40w3KEwWxu5GeYUWzQ&s
            tags:
                - name: CLI
        release:
            version: 1.0.0
            notes: This is the original release
        config:
            - id: 1d476a97-ce34-4271-948f-f436d515f6df
              release:
                  version: 1.0.0
            - id: 0327a412-08e3-4caf-866c-114ef69f917f
              release:
                  version: 1.0.0
    parameters:
        build:
            - name: table_prefix
              type: string
              required: true
              description: The Prefix to be used in table names
            - name: table_suffix
              type: string
              required: false
              description: The Suffix to be used in table names
        run:
            - name: table
              type: object
              required: true
              properties:
                  - name: name
                    type: string
                    required: true
                    description: name of the table
                  - name: primary_key
                    type: string_array
                    required: true
                    description: Primary key of the table
                  - name: columns
                    type: object_array
                    required: true
                    description: Columns of the table
                    properties:
                        - name: name
                          type: string
                          required: true
                          description: name of the column
                        - name: type
                          type: string
                          required: true
                          description: type of the column
                        - name: nullable
                          type: boolean
                          required: true
                          description: nullable of the column
                        - name: default
                          type: string
                          required: true
                          description: default value of the column
    
  • In this example, we define two build parameters and one run parameter at the app level. Here are a few important considerations when defining app parameters:

    • A parameter must be present in at least one block within the app to be defined as an app parameter.

    • The name and type of the parameter must match across all blocks and the app.

    • If a parameter is required in any of the blocks, it must also be defined as required at the app level.

    • For object and object_array parameters, the definition of all properties must be identical across all blocks and the app.

  • We can then create the app spec using the following command:

    peak apps specs create app-spec.yml
    

Deploying the App

  • When deploying the app, we need to provide values for both app and block parameters.

  • A key advantage of app parameters is that we only need to provide values for them once, rather than defining them in every block. Each block will use the app parameter values wherever possible.

    # deploy.yml
    
    body:
        metadata:
            name: app-deploy
            title: App deploy
            summary: App deploy
            description: |
                # App deploy
            descriptionContentType: text/markdown
            imageUrl: https://cdn-icons-png.flaticon.com/512/835/835890.png
            tags:
                - name: CLI
        parameters:
            block-2:
                build:
                    dev_env_id: latest # Value for dev_env_id which isn't present as an app parameter
                    table_suffix: "002" # Override the value of app parameters
        appParameters:
            build:
                table_prefix: dev
                table_suffix: "001"
            run:
                table:
                    name: sktest
                    primary_key:
                        - id
                    columns:
                        - name: id
                          type: number
                          nullable: false
                          default: 1
        revision:
            notes: This is the initial revision
        spec:
            id: d93f4577-483f-442e-9c13-831d7713273e
            release:
                version: 1.0.0
    
  • App parameter values must be defined within a key called appParameters. In this example, we define three parameters: table_prefix, table_suffix, and table.

  • Both blocks will automatically inherit these values without requiring them to be redefined in the parameters section of the configuration.

  • In the example above, block-2 has an additional parameter, dev_env_id, which isn’t defined as an app parameter. Therefore, we specify its value within the parameters section.

  • For block-2, we also want to override the value of table_suffix to 002, so we define it again in the parameters section. Remember, values specified for block parameters will override those defined as app parameters.

  • We can create the app deployment using the following command:

    peak apps deployments create deploy.yml
    
  • This was a simple example, but imagine if we had 10 such blocks. Instead of defining values in 10 places, we only need to define them once, and each block will automatically use the values from the app parameters.

Run Parameters

  • In the example above, both blocks share a run parameter called table. Suppose we want to update the value of this run parameter at a later stage. Here’s the updated configuration:

    # params.yml
    
    body:
        table:
            name: sktest
            primary_key:
                - id
            columns:
                - name: id
                  type: number
                  nullable: false
                  default: 1
                - name: name
                  type: string
                  nullable: false
                  default: ""
    
  • Without app parameters, we would need to update this value individually for each block. To update it, we would run the followingc two commands:

    peak deployments patch-parameters < block-1-deployment-id > params.yml
    peak deployments patch-parameters < block-2-deployment-id > params.yml
    
  • If there were 10 such blocks, we would have to run the command 10 times 😫

  • With app parameters, a single command can update the value across all blocks 🥳 Simply update the value of the app parameter, and every block will automatically inherit the new value:

    peak deployments patch-parameters < app-deployment-id > params.yml