SlackIncomingWebhook icon
Pause icon
Request icon
Log icon

Use conditional inputs to request compute resources and wait for approval

Build a dynamic resource request workflow in Kestra with conditional inputs, a Slack approval message, and a human-in-the-loop pause that resumes on demand.

Categories
CoreInfrastructure

Turn ad hoc resource requests into a governed, auditable workflow. This blueprint shows how to combine Kestra conditional inputs, a Slack approval notification, and a human-in-the-loop pause so that access permissions, SaaS applications, development tools, and cloud VMs are only provisioned after a reviewer signs off. The form adapts to what the requester picks, the approver gets a one-click Slack link, and every decision is captured in the execution history for compliance and IT service management.

How it works

  1. The requester selects a resource_type (Access permissions, SaaS application, Development tool, or Cloud VM). Using the dependsOn property with a condition, only the relevant follow-up inputs appear: access_permissions, saas_applications, development_tools, or the cloud_provider, cloud_vms, and region chain. Option lists are loaded dynamically from the KV store via {{ kv(...) }} expressions.
  2. The send_approval_request task (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) posts an approval message to Slack containing a Resume link back to the execution.
  3. The wait_for_approval task (io.kestra.plugin.core.flow.Pause) halts the execution with onResume fields approved (BOOL) and comment (STRING), waiting for a human decision.
  4. Once resumed, the approve task (io.kestra.plugin.core.http.Request) POSTs the collected {{ inputs }} to a downstream provisioning endpoint.
  5. The log task (io.kestra.plugin.core.log.Log) records the approval comment and the response body for traceability.

What you get

  • A self-service intake form that changes based on the request type.
  • Slack-based approvals with a direct resume link, no extra UI.
  • A built-in audit trail of who requested what and how it was decided.
  • A clean handoff to any provisioning API via an HTTP request.

Who it's for

  • Platform and IT teams running access or infrastructure request queues.
  • DevOps engineers automating cloud VM and tooling provisioning.
  • Ops and compliance owners who need approvals on the record.

Why orchestrate this with Kestra

Slack and KV lists alone cannot pause a process, wait for a human, and resume exactly where it left off. Kestra adds event-driven and API-triggered execution, a durable Pause with typed onResume inputs, retries on the Slack and HTTP calls, full execution lineage, and everything defined declaratively in YAML. The dynamic dependsOn inputs build a smart form that no chat tool or static webhook can replicate.

Prerequisites

  • A running Kestra instance.
  • A Slack incoming webhook URL.
  • KV pairs that populate the dynamic dropdowns (see Quick start).

Secrets

This blueprint uses a mock webhook URL inline for demonstration. In production, replace the url on send_approval_request with your real Slack incoming webhook, ideally stored as a secret and referenced with {{ secret('SLACK_WEBHOOK_URL') }}.

Quick start

  1. Add the required KV pairs (access_permissions, saas_applications, development_tools, cloud_vms, cloud_regions) used by the input expressions:

    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"]
          }
    
  2. Point send_approval_request at your Slack webhook (or its secret).

  3. Run the flow, pick a resource_type, and submit the dynamic form.

  4. Open the Slack message, click Resume, set approved and comment, and watch the flow finish.

How to extend

  • Swap the mock approve URL for your real provisioning API (Terraform Cloud, AWS, GCP, or an ITSM system).
  • Branch on approved with an If task to skip provisioning when rejected.
  • Add labels or a notification on completion to close the loop with the requester.
  • Replace the manual Pause with an approval gate tied to your identity provider.

Links

Orchestrate with Kestra
Orchestrate Slack with Kestra
Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.