{
  "slug": "pilot/executors",
  "title": "Executors",
  "description": "Pilot executor reference — Browser, Terraform, Git, Persist, Shell, HTTP, and Composite.",
  "url": "https://cuitty.com/docs/pilot/executors",
  "markdown_url": "https://cuitty.com/docs/pilot/executors.md",
  "json_url": "https://cuitty.com/docs/pilot/executors.json",
  "frontmatter": {
    "title": "Executors",
    "description": "Pilot executor reference — Browser, Terraform, Git, Persist, Shell, HTTP, and Composite.",
    "order": 3,
    "section": "Pilot",
    "updatedAt": "2026-06-01"
  },
  "headings": [
    {
      "depth": 1,
      "slug": "executors",
      "text": "Executors"
    },
    {
      "depth": 2,
      "slug": "browser-default",
      "text": "Browser (default)"
    },
    {
      "depth": 3,
      "slug": "configuration",
      "text": "Configuration"
    },
    {
      "depth": 2,
      "slug": "terraform",
      "text": "Terraform"
    },
    {
      "depth": 3,
      "slug": "configuration-1",
      "text": "Configuration"
    },
    {
      "depth": 2,
      "slug": "git",
      "text": "Git"
    },
    {
      "depth": 3,
      "slug": "configuration-2",
      "text": "Configuration"
    },
    {
      "depth": 2,
      "slug": "persist",
      "text": "Persist"
    },
    {
      "depth": 3,
      "slug": "configuration-3",
      "text": "Configuration"
    },
    {
      "depth": 2,
      "slug": "shell",
      "text": "Shell"
    },
    {
      "depth": 3,
      "slug": "configuration-4",
      "text": "Configuration"
    },
    {
      "depth": 2,
      "slug": "http",
      "text": "HTTP"
    },
    {
      "depth": 3,
      "slug": "configuration-5",
      "text": "Configuration"
    },
    {
      "depth": 2,
      "slug": "composite",
      "text": "Composite"
    },
    {
      "depth": 3,
      "slug": "example-conditional--parallel",
      "text": "Example: Conditional + parallel"
    },
    {
      "depth": 2,
      "slug": "see-also",
      "text": "See also"
    }
  ],
  "body_markdown": "# Executors\n\nPilot routes each playbook step to an **executor** based on the step's `executor` field or its action prefix. The executor registry resolves the target executor in this order:\n\n1. Explicit `executor` field on the step\n2. Action prefix inference (`tf_` -> terraform, `git_` -> git, etc.)\n3. Default: `browser`\n\n## Browser (default)\n\nThe browser executor drives a Playwright browser instance. It handles all 14 built-in actions: `navigate`, `click`, `fill`, `select`, `set_toggle`, `wait_for`, `assert`, `capture`, `capture_secret`, `ai_decide`, `scroll`, `hover`, `press`, `upload`.\n\nWhen `ai_fallback: true`, a failing selector triggers the AI healing engine, which compares the stored DOM snapshot to the current page and proposes a replacement selector.\n\n### Configuration\n\nNo explicit configuration required. The browser executor starts automatically.\n\n| Env var | Purpose | Default |\n|---------|---------|---------|\n| `CUITTY_AI_KEY` | AI model key for selector healing | (local model) |\n\n## Terraform\n\nWraps the Architect API for infrastructure provisioning. Steps are prefixed with `tf_`.\n\n| Action | Description | Key fields |\n|--------|-------------|------------|\n| `tf_init` | Create or ensure a target | `target_id`, `provider`, `kind` |\n| `tf_validate` | Validate target config | `target_id`, `resource_types` |\n| `tf_plan` | Generate a runtime plan | `target_id`, `resource_types` |\n| `tf_apply` | Apply runtime state | `target_id`, `resource_types` |\n| `tf_destroy` | Destroy runtime resources | `target_id`, `resource_types` |\n| `tf_output` | Read a specific output value | `target_id`, `output_name` |\n| `tf_import` | Import an existing resource | `target_id`, `resource_type`, `resource_id` |\n| `tf_state` | Read full runtime state | `target_id` |\n\nAll Terraform steps accept an optional `capture_as` field and `allow_remote` boolean.\n\n### Configuration\n\n| Env var | Purpose | Default |\n|---------|---------|---------|\n| `PILOT_ARCHITECT_URL` | Architect API base URL | `http://localhost:4470` |\n| `PILOT_EXECUTOR_TERRAFORM` | Enable/disable | `true` |\n\n## Git\n\nWraps the Code API for repository and pull request operations. Steps are prefixed with `git_`.\n\n| Action | Description | Key fields |\n|--------|-------------|------------|\n| `git_clone` | Create a repository | `name`, `visibility`, `auto_init` |\n| `git_branch` | Create a branch | `owner`, `repo`, `name`, `sha` |\n| `git_commit` | Create a commit | `owner`, `repo`, `message` |\n| `git_push` | Push a branch | `owner`, `repo`, `branch` |\n| `git_pr_create` | Open a pull request | `owner`, `repo`, `title`, `head`, `base` |\n| `git_pr_merge` | Merge a pull request | `owner`, `repo`, `number`, `strategy` |\n| `git_tag` | Create a tag | `owner`, `repo`, `tag_name`, `name` |\n| `git_release` | Create a release | `owner`, `repo`, `tag_name`, `name`, `body` |\n\nMerge strategies: `merge`, `squash`, `rebase`, `fast_forward`.\n\n### Configuration\n\n| Env var | Purpose | Default |\n|---------|---------|---------|\n| `PILOT_CODE_URL` | Code API base URL | `http://localhost:4351` |\n| `PILOT_EXECUTOR_GIT` | Enable/disable | `true` |\n\n## Persist\n\nWraps the Persist API for storage provisioning and data management. Steps are prefixed with `persist_`.\n\n| Action | Description | Key fields |\n|--------|-------------|------------|\n| `persist_provision` | Provision storage stores | `profile`, `stores` |\n| `persist_migrate` | Run database migrations | `dry_run` |\n| `persist_sync` | Sync data between stores | |\n| `persist_backup` | Create a backup | |\n| `persist_restore` | Restore from backup | `archive_path` |\n| `persist_proxy_start` | Start the proxy | |\n| `persist_proxy_stop` | Stop the proxy | |\n\n### Configuration\n\n| Env var | Purpose | Default |\n|---------|---------|---------|\n| `PILOT_PERSIST_URL` | Persist API base URL | `http://localhost:4290` |\n| `PILOT_EXECUTOR_PERSIST` | Enable/disable | `true` |\n\n## Shell\n\nExecutes shell commands with an allowlist for security. Steps are prefixed with `shell_`.\n\n| Action | Description | Key fields |\n|--------|-------------|------------|\n| `shell_exec` | Run a single command | `command`, `args`, `env` |\n| `shell_script` | Run a multi-line script | `command` |\n| `shell_assert` | Run a command and assert output | `command`, `assert` |\n\nShell assertions support: `exit_code`, `stdout_contains`, `stderr_empty`.\n\n### Configuration\n\n| Env var | Purpose | Default |\n|---------|---------|---------|\n| `PILOT_EXECUTOR_SHELL` | Enable/disable | `false` (disabled by default) |\n\nThe shell executor uses an `allowedCommands` allowlist in `executor_config`:\n\n```yaml\nexecutor_config:\n  shell:\n    allowedCommands: [\"curl\", \"dig\", \"nslookup\", \"jq\"]\n    timeout: 30000\n```\n\n## HTTP\n\nMakes API requests, polls endpoints, and asserts response contents. Steps are prefixed with `http_`.\n\n| Action | Description | Key fields |\n|--------|-------------|------------|\n| `http_request` | Send an HTTP request | `url`, `method`, `headers`, `body` |\n| `http_assert` | Request + assert response | `url`, `assert` |\n| `http_poll` | Poll until condition met | `url`, `until`, `interval`, `max_attempts` |\n\nHTTP assertions support: `status`, `body_contains`, `header`.\n\n### Configuration\n\n| Env var | Purpose | Default |\n|---------|---------|---------|\n| `PILOT_EXECUTOR_HTTP` | Enable/disable | `true` |\n\nThe HTTP executor supports an `allowedHosts` restriction in `executor_config`:\n\n```yaml\nexecutor_config:\n  http:\n    allowedHosts: [\"api.cloudflare.com\", \"api.github.com\"]\n    timeout: 30000\n```\n\n## Composite\n\nThe composite executor orchestrates other steps. It supports four meta-actions:\n\n| Action | Description | Key fields |\n|--------|-------------|------------|\n| `run_playbook` | Execute another playbook inline | `playbook`, `inputs` |\n| `parallel` | Run step branches concurrently | `branches` |\n| `conditional` | Execute steps if condition is true | `condition`, `then` |\n| `loop` | Repeat steps until condition or max iterations | `until`, `max_iterations`, `steps` |\n\nConditions use the syntax `captures.key == value`, `captures.key != value`, or `captures.key` (truthy check).\n\n### Example: Conditional + parallel\n\n```yaml\nsteps:\n  - id: check-provider\n    action: conditional\n    executor: composite\n    condition: \"captures.provider == cloudflare\"\n    then:\n      - id: setup-dns\n        action: run_playbook\n        playbook: cloudflare.dns.add-a-record\n        inputs:\n          zone: \"{{zone}}\"\n          record_name: \"{{subdomain}}\"\n          ip_address: \"{{ip}}\"\n  - id: deploy-both\n    action: parallel\n    executor: composite\n    branches:\n      - steps:\n          - id: provision-storage\n            action: persist_provision\n            profile: production\n      - steps:\n          - id: apply-infra\n            action: tf_apply\n            target_id: \"{{target}}\"\n            resource_types: [\"aws_s3_bucket\"]\n```\n\n## See also\n\n- [Playbook reference](/docs/pilot/playbook-reference) — full YAML schema\n- [JavaScript SDK](/docs/pilot/sdk/javascript) — run playbooks programmatically\n- [Quickstart](/docs/pilot/quickstart) — record and replay your first workflow",
  "body_html": "<h1 id=\"executors\">Executors</h1>\n<p>Pilot routes each playbook step to an <strong>executor</strong> based on the step’s <code>executor</code> field or its action prefix. The executor registry resolves the target executor in this order:</p>\n<ol>\n<li>Explicit <code>executor</code> field on the step</li>\n<li>Action prefix inference (<code>tf_</code> -> terraform, <code>git_</code> -> git, etc.)</li>\n<li>Default: <code>browser</code></li>\n</ol>\n<h2 id=\"browser-default\">Browser (default)</h2>\n<p>The browser executor drives a Playwright browser instance. It handles all 14 built-in actions: <code>navigate</code>, <code>click</code>, <code>fill</code>, <code>select</code>, <code>set_toggle</code>, <code>wait_for</code>, <code>assert</code>, <code>capture</code>, <code>capture_secret</code>, <code>ai_decide</code>, <code>scroll</code>, <code>hover</code>, <code>press</code>, <code>upload</code>.</p>\n<p>When <code>ai_fallback: true</code>, a failing selector triggers the AI healing engine, which compares the stored DOM snapshot to the current page and proposes a replacement selector.</p>\n<h3 id=\"configuration\">Configuration</h3>\n<p>No explicit configuration required. The browser executor starts automatically.</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Env var</th><th>Purpose</th><th>Default</th></tr></thead><tbody><tr><td><code>CUITTY_AI_KEY</code></td><td>AI model key for selector healing</td><td>(local model)</td></tr></tbody></table>\n<h2 id=\"terraform\">Terraform</h2>\n<p>Wraps the Architect API for infrastructure provisioning. Steps are prefixed with <code>tf_</code>.</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Action</th><th>Description</th><th>Key fields</th></tr></thead><tbody><tr><td><code>tf_init</code></td><td>Create or ensure a target</td><td><code>target_id</code>, <code>provider</code>, <code>kind</code></td></tr><tr><td><code>tf_validate</code></td><td>Validate target config</td><td><code>target_id</code>, <code>resource_types</code></td></tr><tr><td><code>tf_plan</code></td><td>Generate a runtime plan</td><td><code>target_id</code>, <code>resource_types</code></td></tr><tr><td><code>tf_apply</code></td><td>Apply runtime state</td><td><code>target_id</code>, <code>resource_types</code></td></tr><tr><td><code>tf_destroy</code></td><td>Destroy runtime resources</td><td><code>target_id</code>, <code>resource_types</code></td></tr><tr><td><code>tf_output</code></td><td>Read a specific output value</td><td><code>target_id</code>, <code>output_name</code></td></tr><tr><td><code>tf_import</code></td><td>Import an existing resource</td><td><code>target_id</code>, <code>resource_type</code>, <code>resource_id</code></td></tr><tr><td><code>tf_state</code></td><td>Read full runtime state</td><td><code>target_id</code></td></tr></tbody></table>\n<p>All Terraform steps accept an optional <code>capture_as</code> field and <code>allow_remote</code> boolean.</p>\n<h3 id=\"configuration-1\">Configuration</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Env var</th><th>Purpose</th><th>Default</th></tr></thead><tbody><tr><td><code>PILOT_ARCHITECT_URL</code></td><td>Architect API base URL</td><td><code>http://localhost:4470</code></td></tr><tr><td><code>PILOT_EXECUTOR_TERRAFORM</code></td><td>Enable/disable</td><td><code>true</code></td></tr></tbody></table>\n<h2 id=\"git\">Git</h2>\n<p>Wraps the Code API for repository and pull request operations. Steps are prefixed with <code>git_</code>.</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Action</th><th>Description</th><th>Key fields</th></tr></thead><tbody><tr><td><code>git_clone</code></td><td>Create a repository</td><td><code>name</code>, <code>visibility</code>, <code>auto_init</code></td></tr><tr><td><code>git_branch</code></td><td>Create a branch</td><td><code>owner</code>, <code>repo</code>, <code>name</code>, <code>sha</code></td></tr><tr><td><code>git_commit</code></td><td>Create a commit</td><td><code>owner</code>, <code>repo</code>, <code>message</code></td></tr><tr><td><code>git_push</code></td><td>Push a branch</td><td><code>owner</code>, <code>repo</code>, <code>branch</code></td></tr><tr><td><code>git_pr_create</code></td><td>Open a pull request</td><td><code>owner</code>, <code>repo</code>, <code>title</code>, <code>head</code>, <code>base</code></td></tr><tr><td><code>git_pr_merge</code></td><td>Merge a pull request</td><td><code>owner</code>, <code>repo</code>, <code>number</code>, <code>strategy</code></td></tr><tr><td><code>git_tag</code></td><td>Create a tag</td><td><code>owner</code>, <code>repo</code>, <code>tag_name</code>, <code>name</code></td></tr><tr><td><code>git_release</code></td><td>Create a release</td><td><code>owner</code>, <code>repo</code>, <code>tag_name</code>, <code>name</code>, <code>body</code></td></tr></tbody></table>\n<p>Merge strategies: <code>merge</code>, <code>squash</code>, <code>rebase</code>, <code>fast_forward</code>.</p>\n<h3 id=\"configuration-2\">Configuration</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Env var</th><th>Purpose</th><th>Default</th></tr></thead><tbody><tr><td><code>PILOT_CODE_URL</code></td><td>Code API base URL</td><td><code>http://localhost:4351</code></td></tr><tr><td><code>PILOT_EXECUTOR_GIT</code></td><td>Enable/disable</td><td><code>true</code></td></tr></tbody></table>\n<h2 id=\"persist\">Persist</h2>\n<p>Wraps the Persist API for storage provisioning and data management. Steps are prefixed with <code>persist_</code>.</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Action</th><th>Description</th><th>Key fields</th></tr></thead><tbody><tr><td><code>persist_provision</code></td><td>Provision storage stores</td><td><code>profile</code>, <code>stores</code></td></tr><tr><td><code>persist_migrate</code></td><td>Run database migrations</td><td><code>dry_run</code></td></tr><tr><td><code>persist_sync</code></td><td>Sync data between stores</td><td></td></tr><tr><td><code>persist_backup</code></td><td>Create a backup</td><td></td></tr><tr><td><code>persist_restore</code></td><td>Restore from backup</td><td><code>archive_path</code></td></tr><tr><td><code>persist_proxy_start</code></td><td>Start the proxy</td><td></td></tr><tr><td><code>persist_proxy_stop</code></td><td>Stop the proxy</td><td></td></tr></tbody></table>\n<h3 id=\"configuration-3\">Configuration</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Env var</th><th>Purpose</th><th>Default</th></tr></thead><tbody><tr><td><code>PILOT_PERSIST_URL</code></td><td>Persist API base URL</td><td><code>http://localhost:4290</code></td></tr><tr><td><code>PILOT_EXECUTOR_PERSIST</code></td><td>Enable/disable</td><td><code>true</code></td></tr></tbody></table>\n<h2 id=\"shell\">Shell</h2>\n<p>Executes shell commands with an allowlist for security. Steps are prefixed with <code>shell_</code>.</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Action</th><th>Description</th><th>Key fields</th></tr></thead><tbody><tr><td><code>shell_exec</code></td><td>Run a single command</td><td><code>command</code>, <code>args</code>, <code>env</code></td></tr><tr><td><code>shell_script</code></td><td>Run a multi-line script</td><td><code>command</code></td></tr><tr><td><code>shell_assert</code></td><td>Run a command and assert output</td><td><code>command</code>, <code>assert</code></td></tr></tbody></table>\n<p>Shell assertions support: <code>exit_code</code>, <code>stdout_contains</code>, <code>stderr_empty</code>.</p>\n<h3 id=\"configuration-4\">Configuration</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Env var</th><th>Purpose</th><th>Default</th></tr></thead><tbody><tr><td><code>PILOT_EXECUTOR_SHELL</code></td><td>Enable/disable</td><td><code>false</code> (disabled by default)</td></tr></tbody></table>\n<p>The shell executor uses an <code>allowedCommands</code> allowlist in <code>executor_config</code>:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">executor_config</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  shell</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    allowedCommands</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">\"curl\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"dig\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"nslookup\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"jq\"</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    timeout</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">30000</span></span></code></pre>\n<h2 id=\"http\">HTTP</h2>\n<p>Makes API requests, polls endpoints, and asserts response contents. Steps are prefixed with <code>http_</code>.</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Action</th><th>Description</th><th>Key fields</th></tr></thead><tbody><tr><td><code>http_request</code></td><td>Send an HTTP request</td><td><code>url</code>, <code>method</code>, <code>headers</code>, <code>body</code></td></tr><tr><td><code>http_assert</code></td><td>Request + assert response</td><td><code>url</code>, <code>assert</code></td></tr><tr><td><code>http_poll</code></td><td>Poll until condition met</td><td><code>url</code>, <code>until</code>, <code>interval</code>, <code>max_attempts</code></td></tr></tbody></table>\n<p>HTTP assertions support: <code>status</code>, <code>body_contains</code>, <code>header</code>.</p>\n<h3 id=\"configuration-5\">Configuration</h3>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Env var</th><th>Purpose</th><th>Default</th></tr></thead><tbody><tr><td><code>PILOT_EXECUTOR_HTTP</code></td><td>Enable/disable</td><td><code>true</code></td></tr></tbody></table>\n<p>The HTTP executor supports an <code>allowedHosts</code> restriction in <code>executor_config</code>:</p>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">executor_config</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">  http</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    allowedHosts</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">\"api.cloudflare.com\"</span><span style=\"color:#E1E4E8\">, </span><span style=\"color:#9ECBFF\">\"api.github.com\"</span><span style=\"color:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    timeout</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#79B8FF\">30000</span></span></code></pre>\n<h2 id=\"composite\">Composite</h2>\n<p>The composite executor orchestrates other steps. It supports four meta-actions:</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Action</th><th>Description</th><th>Key fields</th></tr></thead><tbody><tr><td><code>run_playbook</code></td><td>Execute another playbook inline</td><td><code>playbook</code>, <code>inputs</code></td></tr><tr><td><code>parallel</code></td><td>Run step branches concurrently</td><td><code>branches</code></td></tr><tr><td><code>conditional</code></td><td>Execute steps if condition is true</td><td><code>condition</code>, <code>then</code></td></tr><tr><td><code>loop</code></td><td>Repeat steps until condition or max iterations</td><td><code>until</code>, <code>max_iterations</code>, <code>steps</code></td></tr></tbody></table>\n<p>Conditions use the syntax <code>captures.key == value</code>, <code>captures.key != value</code>, or <code>captures.key</code> (truthy check).</p>\n<h3 id=\"example-conditional--parallel\">Example: Conditional + parallel</h3>\n<pre class=\"astro-code github-dark\" style=\"background-color:#24292e;color:#e1e4e8; overflow-x: auto;\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#85E89D\">steps</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">check-provider</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    action</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">conditional</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    executor</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">composite</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    condition</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"captures.provider == cloudflare\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    then</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">setup-dns</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">        action</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">run_playbook</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">        playbook</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">cloudflare.dns.add-a-record</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">        inputs</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">          zone</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"{{zone}}\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">          record_name</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"{{subdomain}}\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">          ip_address</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"{{ip}}\"</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">  - </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">deploy-both</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    action</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">parallel</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    executor</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">composite</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">    branches</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#85E89D\">steps</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">          - </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">provision-storage</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">            action</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">persist_provision</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">            profile</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">production</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">      - </span><span style=\"color:#85E89D\">steps</span><span style=\"color:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"color:#E1E4E8\">          - </span><span style=\"color:#85E89D\">id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">apply-infra</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">            action</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">tf_apply</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">            target_id</span><span style=\"color:#E1E4E8\">: </span><span style=\"color:#9ECBFF\">\"{{target}}\"</span></span>\n<span class=\"line\"><span style=\"color:#85E89D\">            resource_types</span><span style=\"color:#E1E4E8\">: [</span><span style=\"color:#9ECBFF\">\"aws_s3_bucket\"</span><span style=\"color:#E1E4E8\">]</span></span></code></pre>\n<h2 id=\"see-also\">See also</h2>\n<ul>\n<li><a href=\"/docs/pilot/playbook-reference\">Playbook reference</a> — full YAML schema</li>\n<li><a href=\"/docs/pilot/sdk/javascript\">JavaScript SDK</a> — run playbooks programmatically</li>\n<li><a href=\"/docs/pilot/quickstart\">Quickstart</a> — record and replay your first workflow</li>\n</ul>",
  "links_out": [
    "/docs/pilot/playbook-reference",
    "/docs/pilot/sdk/javascript",
    "/docs/pilot/quickstart"
  ]
}