> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cortex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Terraform destroy

export const RecipeBadges = ({badges = []}) => {
  const map = {
    "recipe": {
      label: "Recipe",
      color: "#A86400"
    },
    "ai-excellence": {
      label: "AI excellence",
      color: "#653EE8"
    },
    "production-readiness": {
      label: "Production readiness",
      color: "#226686"
    },
    "incident-mgmt": {
      label: "Incident management",
      color: "#86198F"
    },
    "migrations": {
      label: "Migrations",
      color: "#0E7C66"
    },
    "compliance": {
      label: "Compliance",
      color: "#475569"
    },
    "dora": {
      label: "DORA metrics",
      color: "#1D4ED8"
    },
    "security": {
      label: "Security",
      color: "#B42318"
    },
    "operational-readiness": {
      label: "Operational readiness",
      color: "#B54708"
    },
    "dev-onboarding": {
      label: "Developer onboarding",
      color: "#C11574"
    }
  };
  const items = badges.map(key => map[key]).filter(Boolean);
  if (items.length === 0) return null;
  return <div className="not-prose flex flex-wrap gap-2 mb-6">
      {items.map(b => <span key={b.label} className="rounded-lg px-2 py-1 text-xs font-medium" style={{
    backgroundColor: b.color,
    color: b.textColor || "#FFFFFF"
  }}>
          {b.label}
        </span>)}
    </div>;
};

<RecipeBadges badges={["recipe", "production-readiness"]} />

Using a Workflow, you can streamline the process of dismantling infrastructure that was previously provisioned and managed by a Terraform configuration. This Workflow will also remove the resource entity from your Cortex workspace.

## How to use a Workflow in Cortex to destroy a resource with Terraform

### Prerequisite

Before getting started, you should have already followed the guide to [Provision an EC2 instance with Terraform](/guides/production-readiness/terraform/provision).

#### Considerations

* This Workflow makes HTTP calls to [Terraform Cloud](https://www.hashicorp.com/en/products/terraform), but it is possible to call other Terraform orchestrators, such as [Spacelift](https://www.spacelift.io/).
* The Terraform orchestrator you use must have an API call to perform the destroy.

### Step 1: Start creating the Workflow

Follow the steps in the documentation to [create a Workflow](/streamline/workflows/create) and [configure its basic settings](/streamline/workflows/create#creating-a-workflow).

In the Workflow's basic settings, set its scope to apply to the entity type `AWS::EC2::Instance` and the group `terraform`. The prerequisite Workflow [Provision an EC2 instance with Terraform](/guides/production-readiness/terraform/provision) automatically adds the group to the entities it creates.

### Step 2: Add blocks to the Workflow

The instructions on this page describe how to create this Workflow in the Cortex UI, but it is also possible to copy the Workflow YAML and add it to your workspace via the [Cortex CLI](https://pypi.org/project/cortexapps-cli/). This allows you to quickly set up the example configuration then iterate on it for your own use case. Expand the tile below to learn more.

<Accordion title="Workflow YAML instructions">
  To upload the Workflow example YAML into your workspace:

  1. Save the Workflow example YAML file below:

  ```yaml theme={null}
  name: "[Terraform Cloud] Destroy"
  tag: workflow-terraform-destroy
  description: null
  isDraft: true
  filter:
    entityFilter:
      typeFilter:
        types:
        - AWS::EC2::Instance
      entityGroupFilter:
        entityGroups:
        - terraform
        excludedEntityGroups: []
    ownershipScope: ALL
    type: ENTITY
  runResponseTemplate: null
  failedRunResponseTemplate: null
  actions:
  - name: Are You Sure
    slug: are-you-sure
    schema:
      inputs:
      - name: Are You Sure? This will also delete it from the Catalog
        description: null
        key: are-you-sure
        required: true
        defaultValue: false
        type: TOGGLE_FIELD
      inputOverrides: []
      type: USER_INPUT
    outgoingActions:
    - branch
    isRootAction: true
  - name: Branch
    slug: branch
    schema:
      branches:
      - name: "yes"
        slug: "yes"
        outgoingAction: get-descriptor
        expression: "actions[\"are-you-sure\"].outputs[\"are-you-sure\"] == true"
        type: CONDITIONAL
      fallbackBranch: null
      joiningAction: null
      type: CONDITIONAL_BRANCH
    outgoingActions:
    - get-descriptor
    isRootAction: false
  - name: Get Descriptor
    slug: get-descriptor
    schema:
      expression: .context.entity.descriptor
      type: JQ
    outgoingActions:
    - get-workspace-id
    isRootAction: false
  - name: Get Workspace ID
    slug: get-workspace-id
    schema:
      expression: .actions."get-descriptor".outputs.result.info."x-cortex-metadata".terraform."workspace-id"
      type: JQ
    outgoingActions:
    - terraform-destroy
    isRootAction: false
  - name: Terraform Destroy
    slug: terraform-destroy
    schema:
      headers:
        Content-Type: application/vnd.api+json
        Authorization: "Bearer {{context.secrets.tf_token}}"
      httpMethod: POST
      payload: |-
        {
             "data": {
                        "attributes": {
                                       "is-destroy": true,
                                       "message": "Triggered Destroy",
                                       "variables": []
                            },
                         "type":"runs",
                         "relationships": {
                                  "workspace": {
                                                      "data": {
                                                             "type": "workspaces",
                                                             "id": "{{actions.get-workspace-id.outputs.result}}"
                                                        }
                                    }
                         }
                  }
        }
      url: https://app.terraform.io/api/v2/runs
      type: HTTP_REQUEST
    outgoingActions:
    - delete-entity
    isRootAction: false
  - name: Delete entity
    slug: delete-entity
    schema:
      inputs:
        entityId: "{{context.entity.tag}}"
      integrationAlias: null
      actionIdentifier: cortex.deleteEntity
      type: ADVANCED_HTTP_REQUEST
    outgoingActions: []
    isRootAction: false
  runRestrictionPolicies: []
  iconTag: null
  variables: []
  ```

  2. Use the [Cortex CLI](https://pypi.org/project/cortexapps-cli/) to run this command, using the path to your Workflow YAML file:<br />
     `cortex workflows create -f <path-to-your-workflow.yaml>`
</Accordion>

Expand the tiles below to learn about each block in this Workflow and how to configure them in the Cortex UI:

<AccordionGroup>
  <Accordion title="User input">
    This block prompts the user to confirm that they want to destroy the resource.

    1. Click **+** in the center of the page. In the block library modal, choose **User input**.
    2. In the block configuration side panel, enter a name and unique slug for this block.
       * In this example, we use the name `Are you sure` and the slug `are-you-sure`.
    3. Click **+Add user input**. Add the following:
       * **Name**: Are you sure? This will also delete it from the catalog
       * **Key**: are-you-sure
       * **Type**: Toggle
       * **Default value**: This is set to `False` to prevent accidental deletion.
       * Click **Add input**.
    4. Save the block.
  </Accordion>

  <Accordion title="Branch">
    During the previous User input step, if the user selects "Yes" when prompted, the Workflow will branch into a set of blocks to destroy the resource. If the user does not select yes, then the Workflow will not continue.

    1. Click **+** in the center of the page. In the block library modal, choose **Branch**.
    2. In the block configuration side panel, enter a name and unique slug for this block.
       * In this example, we use the name `Branch` and the slug `branch`.
    3. Configure the conditional path:
       * **Name**: Yes
       * **Slug**: yes
       * **Path expression**: `actions["are-you-sure"].outputs["are-you-sure"] == true`

    #### Add blocks to the branched path

    The blocks in the path will get the entity descriptor and workspace ID, send an HTTP request to Terraform to destroy the resource, and delete the entity in your Cortex workspace.

    **Data transformations**

    1. Click **+** under the new path. In the block library modal, choose **Data transformation**.
    2. In the block configuration side panel, enter a name and unique slug for this block.
       * In this example, we use the name `Get descriptor` and the slug `get-descriptor`.
    3. Enter a jq expression:

    ```jq theme={null}
    .context.entity.descriptor
    ```

    4. Save the block.
    5. Click **+** under the path. In the block library modal, choose **Data transformation**.
    6. In the block configuration side panel, enter a name and unique slug for this block. In this example, we use the name `Get workspace ID` and the slug `get-workspace-id`.
    7. Enter a jq expression:

       ```jq theme={null}
       .actions."get-descriptor".outputs.result.info."x-cortex-metadata".terraform."workspace-id"
       ```
    8. Save the block.

    **HTTP request**

    1. Click **+** under the new path. In the block library modal, choose **HTTP request**.
    2. In the block configuration side panel, enter a name and unique slug for this block.
       * In this example, we use the name `Terraform destroy` and the slug `terraform-destroy`.
    3. Configure the block:
       * **HTTP method**: POST
       * **URL**: In our example, we set this to:<br />
         `https://app.terraform.io/api/v2/runs`
       * **Headers**: Set the following headers:
         * `Content-Type`: `application/vnd.api+json`
         * `Authorization`: `Bearer {{ context.secrets.tf_token }}`
       * **Payload**: In our example, we enter the following:

    ```json theme={null}
    {
         "data": {
                    "attributes": {
                                   "is-destroy": true,
                                   "message": "Triggered Destroy",
                                   "variables": []
                        },
                     "type":"runs",
                     "relationships": {
                              "workspace": {
                                                  "data": {
                                                         "type": "workspaces",
                                                         "id": "{{actions.get-workspace-id.outputs.result}}"
                                                    }
                                }
                     }
              }
    }
    ```

    4. Save the block.

    **Delete entity**

    1. Click **+** under the new path. In the block library modal, choose **Cortex > Delete entity**.
    2. In the block configuration side panel, enter a name and unique slug for this block.
       1. In this example, we use the name `Delete entity` and the slug `delete-entity`.
    3. Under **Entity ID or tag**, enter `{{context.entity.tag}}`.
  </Accordion>
</AccordionGroup>

### Step 3: Run the Workflow

When you run the Workflow, the following events happen:

* The User input step prompts the user to confirm that they want to delete a resource.
* If the user confirms during the first block, then the branch block runs.
* The Workflow obtains the entity descriptor, then uses that information to obtain the related workspace ID.
* The HTTP request triggers a destroy in Terraform.
* The "Delete entity" step uses the entity descriptor obtained in the previous steps to determine which entity to delete.


## Related topics

- [Managing Terraform infra in Cortex](/ingesting-data-into-cortex/entities-overview/entities/terraform.md)
- [Manage Terraform infrastructure](/guides/production-readiness/terraform.md)
- [Workflows](/guides/product-areas/workflows.md)
