Back to Blog
Guide

Terraform Slack Provider: Channels Tested with Plan, Import and Destroy

We ran the pablovarela/slack Terraform provider against a real Slack workspace: create, update, drift, import, adopt and destroy a channel, plus the exact errors for bad names and missing scopes.

Slack Green Team
October 6, 2026
October 6, 2026
5 min read
Share:
slack api
terraform

The Terraform provider most people use for Slack is pablovarela/slack. It manages channels (slack_conversation) and user groups (slack_usergroup) with a bot token, and it still works. On 6 October 2026 we ran it, version 1.2.2 with Terraform 1.5.7, against our free-plan test workspace and a throwaway Slack app. Create, update, import, adopt and destroy all worked. Five things did not behave the way the docs suggest, and the errors are below.

Check the maintenance status first. Version 1.2.2 came out on 14 April 2023, and the GitHub repository is now archived (read-only). It still has about 5.4 million downloads on the Terraform Registry. Two newer providers exist, but neither replaces it for channels:

ProviderLatest releaseWhat it manages
pablovarela/slack1.2.2, 14 Apr 2023 (repo archived)slack_conversation, slack_usergroup
Essent/slack1.0.3, 18 Sep 2026slack_usergroup only, plus user and conversation data sources
gfnogueira/slack0.2.0, 6 Nov 2025slack_channel

We tested only pablovarela/slack. Release dates are from the registry API on 6 October 2026.

The config we applied

terraform {
  required_providers {
    slack = {
      source  = "pablovarela/slack"
      version = "~> 1.2"
    }
  }
}

provider "slack" {}  # reads SLACK_TOKEN

resource "slack_conversation" "deploys" {
  name              = "sglab-tf-deploys"
  topic             = "Deploy notices from CI"
  purpose           = "Created by Terraform on 6 Oct 2026"
  is_private        = false
  action_on_destroy = "archive"
}

The provider reads the token from the SLACK_TOKEN environment variable, or from token in the provider block. We used a bot token (xoxb-) from an app with channels:manage, channels:read, channels:join, groups:read and users:read. If you do not have one yet, our bot token guide shows where Slack shows it.

terraform init downloaded the provider in a few seconds. terraform apply printed Creation complete after 4s [id=C0C72E17H1S]. The channel had the topic and description, and the bot was its creator and only member. Each change shows up in the channel as a system message:

Slack channel sglab-tf-deploys, archived, showing the system messages from our Terraform runs: sglab1006 joined, set the channel topic, set the channel description, set the topic again, our hand edit, Terraform setting it back, and sglab1006 archived the channel

Updates and drift

We changed topic and ran terraform plan:

  ~ resource "slack_conversation" "deploys" {
      ~ topic = "Deploy notices from CI" -> "Deploy notices from CI, prod only"
Plan: 0 to add, 1 to change, 0 to destroy.

The apply took 2 seconds and changed the topic in place, so the channel ID and history stayed. Then we edited the topic by hand through the API, as a person would in Slack. The next plan put it back:

      ~ topic = "Edited by hand in Slack" -> "Deploy notices from CI, prod only"

So once a channel is in Terraform, people's edits to the topic or description get overwritten on the next apply. If people should own the topic, leave topic out of the config.

Import and adopt an existing channel

There are two ways to put a channel someone made by hand under Terraform: terraform import, or adopt_existing_channel = true. We tried both.

Import. We made #sglab-tf-existing with a description, added a matching resource with only name and is_private, and ran terraform import slack_conversation.existing C0C72E6429J. The import worked. The first apply then failed:

Error: couldn't set conversation purpose : not_in_channel

Import does not add the bot to the channel, and the bot cannot change a channel it is not in. After the bot joined, the apply worked. It also set the description to empty, because our config had no purpose. The plan had said so (- purpose = "Made by hand before Terraform" -> null), but that line is easy to miss. Copy the current topic and purpose into the config before you import.

Adopt. With adopt_existing_channel = true and the name of a channel that already exists, apply reported Creation complete on our hand-made #sglab-tf-adopt. The provider found the channel by name, joined it (the bot was not a member before), and set the topic. No import command and no channel ID needed. This is the easier path for public channels.

Never appear "away" on Slack again

Cloud-based. No downloads. Works 24/7 even when your laptop is off.

Destroy, and the name that stays taken

terraform destroy with the default action_on_destroy = "archive" archived all three channels in about 1 second each. Slack keeps archived channels, and their names stay taken. Running the same config again failed:

Error: could not create conversation sglab-tf-deploys: name_taken

Adding adopt_existing_channel = true did not help, because the provider looks only at channels that are not archived:

Error: could not create conversation sglab-tf-deploys: could not find channel with name sglab-tf-deploys

To reuse the name, unarchive the channel in Slack and adopt it, or delete it first. A Workspace Admin can delete a channel from its settings. With action_on_destroy = "none" Terraform leaves the channel as it is, and the next apply with the same name fails with name_taken.

Errors we got, and what each means

Every error comes back from Slack's conversations.create and the provider prints it after the channel name:

What we triedError
name = "Deploys Prod!"invalid_name_specials
name = "sglab-TF-Upper" (capital letters)invalid_name_specials
A name of 81 charactersinvalid_name_maxlength
A name already used by a channel, archived or notname_taken
is_private = true with a bot that has no groups:writemissing_scope
Same config with a user token that has no channels:managemissing_scope
slack_usergroup with a bot that has no usergroups:writemissing_scope
Change a channel the bot is not innot_in_channel

Capital letters fail. Slack does not lowercase the name for you through the API, so Deploys will not work and deploys will. Use lowercase letters, numbers, hyphens and underscores, up to 80 characters. For missing_scope, add the scope in your app's OAuth & Permissions page and reinstall the app, then use the token it gives you. The missing_scope page shows how to read which scope Slack wanted.

User groups are a paid feature. On our free workspace, Slack's own API refused to create one with paid_teams_only when we tested it for our user groups page, so slack_usergroup is for paid workspaces.

Slack notifications from Terraform

None of these providers sends messages. For "notify Slack when Terraform runs", post to an incoming webhook from your CI job after terraform apply. Terraform cannot create the webhook either: Slack makes webhooks only during an app install.

FAQ

Is the pablovarela Slack provider still safe to use?

It works with Slack's current API as of 6 October 2026: create, update, import, adopt and destroy all worked in our test. The repository is archived, so bugs will not be fixed and new Slack features will not be added. Pin the version (~> 1.2) so a fork does not replace it by surprise.

Can Terraform create a Slack app?

No. None of the three providers manages apps. Slack's App Manifest API (apps.manifest.create) can, but it needs an app configuration token, and no provider wraps it.

Which token type should I use?

A bot token. A user token also works if it carries the same scopes, but every change then shows your name in the channel instead of the bot's.

Always Active

Stop Jiggling Your Mouse.

Join hundreds of remote workers who never worry about their Slack status. Set it up once, stay green forever.

Related Articles

Guide

Alertmanager Slack Config: slack_configs Example and Templates, Tested

A tested alertmanager.yml for Slack, the messages Prometheus alerts produced, a custom title and text template, and what send_resolved, group_by and color changed. Plus a typo amtool did not catch.

Slack Green Team
Guide

Grafana Slack Alerts: Webhook vs Bot Token, Templates, Tested

We sent Grafana alerts to Slack through both kinds of contact point, then replaced the default message with a notification template. The messages Slack showed, the delays, the template we used and the errors Grafana logged.

Slack Green Team
Guide

Jenkins Slack Notification: slackSend Pipeline Tested with a Bot Token

We ran the Jenkins Slack Notification plugin against a real Slack app: the pipeline that worked, the botUser setting that makes slackSend fail with a 404, threads, Block Kit, and the errors for channels the bot cannot see.

Slack Green Team