Skip to main content

Command Palette

Search for a command to run...

Automatically Generate Terraform Actions in Your Codebase with Terraform-Actionize

Updated
5 min read
Automatically Generate Terraform Actions in Your Codebase with Terraform-Actionize
C
Cody is a Senior Cloud Engineer at Oshkosh Corporation, HashiCorp Terraform Professional, and open source contributor. He creates IaC patterns, publishes Terraform modules, and shares platform engineering content so developers everywhere can build better infrastructure, faster.

You just learned of a security leak on a service your team manages at 3:33am — what will you do? Will you peck around in the portal or try to remember the CLI command that rotates the keys? Welcome to the wild west of incident response. If you've been there, you already know the vibe:

It doesn't have to be this way.

Terraform Actions answer the "how to fix it" when things go wrong

Last year at HashiConf, Terraform Actions were revealed to tackle Day-2 operations. Terraform is a fantastic infrastructure provisioning tool, but what do you reach for once it's running? Tasks like credential rotation, start/stopping machines, triggering failovers, purging caches are all part of a Cloud Engineer's wheelhouse. Before Terraform Actions released, the "how" lived somewhere else: a script on your coworker's computer, an outdated runbook, or maybe nothing at all other than a raw drive to fix the problem yesterday. Now that Terraform Actions exist — have you updated all of your configs to include them?

Introducing Terraform-Actionize

Actions exist for major cloud providers like AWS and Azure (of which you may be interested in unlocking many more using AzAPI), but until now you had to know what to look for in the first place. Even if you did, you'd still have to implement them for every single resource — and for a years-old Terraform codebase, that's no small task. That changes with Terraform-Actionize.

Terraform-Actionize is a Claude Code skill that analyzes your Terraform configuration and surfaces every available Action for your resources: then it generates the HCL and invocation commands for you.

Getting started takes about 30 seconds:

git clone https://github.com/codycodescloud/terraform-actionize.git ~/terraform-actionize

ln -s ~/terraform-actionize/terraform-actionize ~/.claude/skills/terraform-actionize

Then in any Claude Code session inside your Terraform project:

/terraform-actionize

That's it. From there the skill walks you through everything.

How it Works

Terraform-Actionize scans your .tf files and version constraints before surfacing available actions.

The skill presents each available action with context, letting you choose exactly what gets added and where: co-located with resources or consolidated in an actions.tf.

After generating the actions, Terraform-Actionize offers to create an actionize.md — a ready-to-use invoke reference your whole team can run from day one.

Here are the actions generated for an Azure App Service:

# Invoke: terraform apply -invoke=action.azapi_resource_action.restart_web_app -var-file=this.tfvars
action "azapi_resource_action" "restart_web_app" {
  config {
    type        = "Microsoft.Web/sites@2024-11-01"
    resource_id = azurerm_linux_web_app.example.id
    action      = "restart"
    method      = "POST"
    body        = {}
    query_parameters = {
      softRestart = ["false"]
      synchronous = ["true"]
    }
  }
}

# Invoke: terraform apply -invoke=action.azapi_resource_action.start_web_app -var-file=this.tfvars
action "azapi_resource_action" "start_web_app" {
  config {
    type        = "Microsoft.Web/sites@2024-11-01"
    resource_id = azurerm_linux_web_app.example.id
    action      = "start"
    method      = "POST"
    body        = {}
  }
}

# Invoke: terraform apply -invoke=action.azapi_resource_action.stop_web_app -var-file=this.tfvars
action "azapi_resource_action" "stop_web_app" {
  config {
    type        = "Microsoft.Web/sites@2024-11-01"
    resource_id = azurerm_linux_web_app.example.id
    action      = "stop"
    method      = "POST"
    body        = {}
  }
}

# Swap a named slot into production. Set targetSlot to the source slot name (e.g. "staging").
# Invoke: terraform apply -invoke=action.azapi_resource_action.swap_slots_to_production -var-file=this.tfvars
action "azapi_resource_action" "swap_slots_to_production" {
  config {
    type        = "Microsoft.Web/sites@2024-11-01"
    resource_id = azurerm_linux_web_app.example.id
    action      = "slotsswap"
    method      = "POST"
    body = {
      targetSlot   = "staging"
      preserveVnet = true
    }
  }
}

And a Storage Account:

# Invoke: terraform apply -invoke=action.azapi_resource_action.rotate_storage_key1 -var-file=this.tfvars
action "azapi_resource_action" "rotate_storage_key1" {
  config {
    type        = "Microsoft.Storage/storageAccounts@2024-01-01"
    resource_id = azurerm_storage_account.example.id
    action      = "regenerateKey"
    method      = "POST"
    body = {
      keyName = "key1"
    }
  }
}

# Invoke: terraform apply -invoke=action.azapi_resource_action.rotate_storage_key2 -var-file=this.tfvars
action "azapi_resource_action" "rotate_storage_key2" {
  config {
    type        = "Microsoft.Storage/storageAccounts@2024-01-01"
    resource_id = azurerm_storage_account.example.id
    action      = "regenerateKey"
    method      = "POST"
    body = {
      keyName = "key2"
    }
  }
}

Here's the actionize.md it generated, which serves as a ready-to-run invoke reference for every action in the codebase:

# Actions — invoke reference

All commands must be run from within the relevant module directory.

---

## containerapp/

### Rotate storage account key1

Regenerates access key `key1` on the example Azure Files storage account.

```bash
cd containerapp
terraform apply -invoke=action.azapi_resource_action.rotate_storage_key1 -var-file=this.tfvars
```

### Rotate storage account key2

Regenerates access key `key2` on the example Azure Files storage account.

```bash
cd containerapp
terraform apply -invoke=action.azapi_resource_action.rotate_storage_key2 -var-file=this.tfvars
```

> **Note:** After rotating a key, update any services or secrets that depend on the rotated key before rotating the other.

---

Truncated - all or select actions can be shared in the actionize.md

Now the next time that 3:33am page comes in, the fix is already in your codebase: it's documented, authenticated, and just a command away. And if you're not the one on call, your teammates will know exactly what to run without waking you up to ask.

The actions generated lean heavily on AzAPI's gateway action — if you want to understand what's happening under the hood, read the AzAPI post.

Try Terraform-Actionize today: github.com/codycodescloud/terraform-actionize

Until next time!

J

I have an idea and your expertise is extremely fit with this. Would love to connect and get your thoughts if you're open to it.

C

Joel, thank you for your support! Sure feel free to share your idea with me at codycodescloud on the major platforms.

J

Really enjoyed your Terraform-Actionize post.

The part that stood out to me was turning Day-2 operations into documented Terraform Actions. Most teams automate provisioning, but operational actions still live in runbooks, scripts, or someone's memory. Your approach solves a real problem.

J

Hello Cody! Nice to meet you.