<p>I made some experiments with <code>terraform</code>, <code>kubernetes</code>, <code>cassandra</code> and <code>elassandra</code>, I separated all by modules, but now I can't delete a specific module.</p>

<p>I'm using <code>gitlab-ci</code>, and I store the terraform states on a AWS backend.
This mean that, every time that I change the infrastructure in terraform files, after a <code>git push</code>, the infrastructure will be updated with an <code>gitlab-ci</code> that run <code>terraform init</code>, <code>terraform plan</code> and <code>terraform apply</code>.</p>

<p><strong>My terraform main file is this:</strong></p>

<pre><code># main.tf
##########################################################################################################################################
# BACKEND                                                                                                                                #
##########################################################################################################################################

terraform {
  backend "s3" {}
}

data "terraform_remote_state" "state" {
  backend = "s3"
  config {
    bucket         = "${var.tf_state_bucket}"
    dynamodb_table = "${var.tf_state_table}"
    region         = "${var.aws-region}"
    key            = "${var.tf_key}"
  }
}

##########################################################################################################################################
# Modules                                                                                                                                #
##########################################################################################################################################

# Cloud Providers: -----------------------------------------------------------------------------------------------------------------------
module "gke" {
  source    = "./gke"
  project   = "${var.gcloud_project}"
  workspace = "${terraform.workspace}"
  region    = "${var.region}"
  zone      = "${var.gcloud-zone}"
  username  = "${var.username}"
  password  = "${var.password}"
}

module "aws" {
  source   = "./aws-config"
  aws-region      = "${var.aws-region}"
  aws-access_key  = "${var.aws-access_key}"
  aws-secret_key  = "${var.aws-secret_key}"
}

# Elassandra: ----------------------------------------------------------------------------------------------------------------------------
module "k8s-elassandra" {
  source   = "./k8s-elassandra"

  host     = "${module.gke.host}"
  username = "${var.username}"
  password = "${var.password}"

  client_certificate     = "${module.gke.client_certificate}"
  client_key             = "${module.gke.client_key}"
  cluster_ca_certificate = "${module.gke.cluster_ca_certificate}"
}

# Cassandra: ----------------------------------------------------------------------------------------------------------------------------
 module "k8s-cassandra" { 
   source   = "./k8s-cassandra"

   host     = "${module.gke.host}"
   username = "${var.username}"
   password = "${var.password}"

   client_certificate     = "${module.gke.client_certificate}"
   client_key             = "${module.gke.client_key}"
   cluster_ca_certificate = "${module.gke.cluster_ca_certificate}"
 }
</code></pre>

<p><strong>This is a tree of my directory:</strong></p>

<pre><code>.
├── aws-config
│   ├── terraform_s3.tf
│   └── variables.tf
├── gke
│   ├── cluster.tf
│   ├── gcloud_access_key.json
│   ├── gcp.tf
│   └── variables.tf
├── k8s-cassandra
│   ├── k8s.tf
│   ├── limit_ranges.tf
│   ├── quotas.tf
│   ├── services.tf
│   ├── stateful_set.tf
│   └── variables.tf
├── k8s-elassandra
│   ├── k8s.tf
│   ├── limit_ranges.tf
│   ├── quotas.tf
│   ├── services.tf
│   ├── stateful_set.tf
│   └── variables.tf
├── main.tf
└── variables.tf
</code></pre>

<p><strong>I'm blocked here:</strong></p>

<p>-> I want to remove the module <code>k8s-cassandra</code></p>

<ul>
<li>If I comment ou delete the module in <code>main.tf</code> (<code>module "k8s-cassandra" {...</code>), I receive this error: </li>
</ul>

<blockquote>
  <p>TERRAFORM PLAN...
  Acquiring state lock. This may take a few moments...
  Releasing state lock. This may take a few moments...</p>
  
  <p><strong>Error: module.k8s-cassandra.kubernetes_stateful_set.cassandra: configuration for module.k8s-cassandra.provider.kubernetes is not present; a provider configuration block is required for all operations</strong></p>
</blockquote>

<ul>
<li>If I insert <code>terraform destroy -target=module.k8s-cassandra -auto-approve</code> between <code>terraform init</code> and <code>terraform plan</code> stills not working.</li>
</ul>

<p>Anyone can help me, please?
Thanks :)</p>

Rui Martins
<p>The meaning of this error message is that Terraform was relying on a <code>provider "kubernetes"</code> block inside the <code>k8s-cassandra</code> module in order to configure the AWS provider. By removing the module from source code, you've implicitly removed that configuration and so the existing objects already present in the state cannot be deleted -- the provider configuration needed to do that is not present.</p>

<p>Although Terraform allows <code>provider</code> blocks inside child modules for flexibility, the documentation recommends keeping all of them in the root module and passing the provider configurations by name into the child modules using a <code>providers</code> map, or by automatic inheritance by name.</p>

<pre><code>provider "kubernetes" {
  # global kubernetes provider config
}

module "k8s-cassandra" {
  # ...module arguments...

  # provider "kubernetes" is automatically inherited by default, but you
  # can also set it explicitly:
  providers = {
    "kubernetes" = "kubernetes"
  }
}
</code></pre>

<p>To get out of the conflict situation you have already though, the answer is to temporarily restore the <code>module "k8s-cassandra"</code> block and then destroy the objects it is managing <em>before</em> removing it, using the <code>-target</code> option:</p>

<pre><code>terraform destroy -target module.k8s-cassandra
</code></pre>

<p>Once all of the objects managed by that module have been destroyed and removed from the state, you can then safely remove the <code>module "k8s-cassandra"</code> block from configuration.</p>

<p>To prevent this from happening again, you should rework the root and child modules here so that the provider configurations are all in the root module, and child modules only inherit provider configurations passed in from the root. For more information, see <a href="https://www.terraform.io/docs/modules/usage.html#providers-within-modules" rel="noreferrer">Providers Within Modules</a> in the documentation.</p>
