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
andtable_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
andobject_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
, andtable
.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 theparameters
section.For block-2, we also want to override the value of
table_suffix
to002
, so we define it again in theparameters
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