Blueprints

Use conditional inputs to request compute resources and wait for approval

Source

yaml
id: request-resources
namespace: company.team

inputs:
  - id: resource_type
    displayName: Resource Type
    type: SELECT
    required: true
    values:
      - Access permissions
      - SaaS application
      - Development tool
      - Cloud VM

  - id: access_permissions
    displayName: Access Permissions
    type: SELECT
    expression: "{{ kv('access_permissions') }}"
    allowCustomValue: true
    dependsOn:
      inputs:
        - resource_type
      condition: "{{ inputs.resource_type equals 'Access permissions' }}"

  - id: saas_applications
    displayName: SaaS Application
    type: MULTISELECT
    expression: "{{ kv('saas_applications') }}"
    allowCustomValue: true
    dependsOn:
      inputs:
        - resource_type
      condition: "{{ inputs.resource_type equals 'SaaS application' }}"

  - id: development_tools
    displayName: Development Tool
    type: SELECT
    expression: "{{ kv('development_tools') }}"
    allowCustomValue: true
    dependsOn:
      inputs:
        - resource_type
      condition: "{{ inputs.resource_type equals 'Development tool' }}"

  - id: cloud_provider
    displayName: Cloud Provider
    type: SELECT
    values:
      - AWS
      - GCP
      - Azure
    dependsOn:
      inputs:
        - resource_type
      condition: "{{ inputs.resource_type equals 'Cloud VM' }}"

  - id: cloud_vms
    displayName: Cloud VM
    type: SELECT
    expression: "{{ kv('cloud_vms')[inputs.cloud_provider] }}"
    allowCustomValue: true
    dependsOn:
      inputs:
        - resource_type
        - cloud_provider
      condition: "{{ inputs.resource_type equals 'Cloud VM' }}"

  - id: region
    displayName: Cloud Region
    type: SELECT
    expression: "{{ kv('cloud_regions')[inputs.cloud_provider] }}"
    dependsOn:
      inputs:
        - resource_type
        - cloud_provider
        - cloud_vms
      condition: "{{ inputs.resource_type equals 'Cloud VM' }}"

variables:
  slack_message: >
    Validate resource request.

    To approve the request, click on the Resume button here

    http://localhost:28080/ui/executions/{{flow.namespace}}/{{flow.id}}/{{execution.id}}.

tasks:
  - id: send_approval_request
    type: io.kestra.plugin.notifications.slack.SlackIncomingWebhook
    url: https://reqres.in/api/slack
    payload: |
      {
        "channel": "#devops",
        "text": {{ render(vars.slack_message) | json }}
      }

  - id: wait_for_approval
    type: io.kestra.plugin.core.flow.Pause
    onResume:
      - id: approved
        description: Whether to approve the request
        type: BOOLEAN
        defaults: true
      - id: comment
        description: Extra comments about the provisioned resources
        type: STRING
        defaults: All requested resources are approved

  - id: approve
    type: io.kestra.plugin.core.http.Request
    uri: https://reqres.in/api/resources
    method: POST
    contentType: application/json
    body: "{{ inputs }}"

  - id: log
    type: io.kestra.plugin.core.log.Log
    message: |
      Status of the request {{ outputs.wait_for_approval.onResume.comment }}.
      Process finished with {{ outputs.approve.body }}.

About this blueprint

Inputs If

This flow shows how to use conditional inputs to build dynamic approval workflows. The workflow takes user input and sends those in a Slack message for approval — the execution is paused until manually resumed.

Using the dependsOn input property, you can set up a chain of dependencies, where one input depends on other inputs or conditions. In this example, the access_permissions, saas_applications, development_tools, and cloud_vms inputs are conditionally displayed based on the chosen resource_type input value.

Before running this flow, make sure to add the required KV pairs e.g. by using the following flow:

yaml
id: add_kv_pairs
namespace: company.team

tasks:
  - id: access_permissions
    type: io.kestra.plugin.core.kv.Set
    key: "{{ task.id }}"
    kvType: JSON
    value: |
      ["Admin", "Developer", "Editor", "Launcher", "Viewer"]

  - id: saas_applications
    type: io.kestra.plugin.core.kv.Set
    key: "{{ task.id }}"
    kvType: JSON
    value: |
      ["Slack", "Notion", "HubSpot", "GitHub", "Jira"]

  - id: development_tools
    type: io.kestra.plugin.core.kv.Set
    key: "{{ task.id }}"
    kvType: JSON
    value: |
      ["Cursor", "IntelliJ IDEA", "PyCharm Professional", "Datagrip"]

  - id: cloud_vms
    type: io.kestra.plugin.core.kv.Set
    key: "{{ task.id }}"
    kvType: JSON
    value: |
      {
        "AWS": ["t2.micro", "t2.small", "t2.medium", "t2.large"],
        "GCP": ["f1-micro", "g1-small", "n1-standard-1", "n1-standard-2"],
        "Azure": ["Standard_B1s", "Standard_B1ms", "Standard_B2s", "Standard_B2ms"]
      }

  - id: cloud_regions
    type: io.kestra.plugin.core.kv.Set
    key: "{{ task.id }}"
    kvType: JSON
    value: |
      {
        "AWS": ["us-east-1", "us-west-1", "us-west-2", "eu-west-1"],
        "GCP": ["us-central1", "us-east1", "us-west1", "europe-west1"],
        "Azure": ["eastus", "westus", "centralus", "northcentralus"]
      }

Slack Incoming Webhook

Pause

Request

Log

New to Kestra?

Use blueprints to kickstart your first workflows.

Get started with Kestra