Terraform destroy
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.
Considerations
This Workflow makes HTTP calls to Terraform Cloud, but it is possible to call other Terraform orchestrators, such as Spacelift.
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 and configure its basic settings.
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 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. 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.
Workflow YAML instructions
To upload the Workflow example YAML into your workspace:
Save the Workflow example YAML file below:
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: []Use the Cortex CLI to run this command, using the path to your Workflow YAML file:
cortex workflows create -f <path-to-your-workflow.yaml>
Expand the tiles below to learn about each block in this Workflow and how to configure them in the Cortex UI:
User input
This block prompts the user to confirm that they want to destroy the resource.
Click + in the center of the page. In the block library modal, choose User input.
In the block configuration side panel, enter a name and unique slug for this block.
In this example, we use the name
Are you sureand the slugare-you-sure.
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
Falseto prevent accidental deletion.Click Add input.
Save the block.
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.
Click + in the center of the page. In the block library modal, choose Branch.
In the block configuration side panel, enter a name and unique slug for this block.
In this example, we use the name
Branchand the slugbranch.
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
Click + under the new path. In the block library modal, choose Data transformation.
In the block configuration side panel, enter a name and unique slug for this block.
In this example, we use the name
Get descriptorand the slugget-descriptor.
Enter a jq expression:
Save the block.
Click + under the path. In the block library modal, choose Data transformation.
In the block configuration side panel, enter a name and unique slug for this block. In this example, we use the name
Get workspace IDand the slugget-workspace-id.Enter a jq expression:
Save the block.
HTTP request
Click + under the new path. In the block library modal, choose HTTP request.
In the block configuration side panel, enter a name and unique slug for this block.
In this example, we use the name
Terraform destroyand the slugterraform-destroy.
Configure the block:
HTTP method: POST
URL: In our example, we set this to:
https://app.terraform.io/api/v2/runsHeaders: Set the following headers:
Content-Type:application/vnd.api+jsonAuthorization:Bearer {{ context.secrets.tf_token }}
Payload: In our example, we enter the following:
Save the block.
Delete entity
Click + under the new path. In the block library modal, choose Cortex > Delete entity.
In the block configuration side panel, enter a name and unique slug for this block.
In this example, we use the name
Delete entityand the slugdelete-entity.
Under Entity ID or tag, enter
{{context.entity.tag}}.
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.
Last updated
Was this helpful?