hashicorp / terraform-provider-mysql

Terraform MySQL provider – This Terraform provider is archived per our provider archiving process: https://terraform.io/docs/internals/archiving.html
https://www.terraform.io/docs/providers/mysql/
Mozilla Public License 2.0
61 stars 189 forks source link

Hard to get rid of mysql provider when it's no longer needed in a project #38

Open fabiendelpierre opened 6 years ago

fabiendelpierre commented 6 years ago

Hi there,

So firstly I'm not sure if this is an issue with the mysql provider, or with Terraform itself, or something else... sorry if it's got nothing to do with this provider.

This is with macOS Terraform v0.11.7 and mysql provider v1.1.0.

I have a super simple setup like this:

resource "aws_db_instance" "fun_db" {
  ...
}

provider "mysql" {
  endpoint  = "${aws_db_instance.fun_db.address}"
  username  = "fun_admin"
  password  = "fun_admin123"
}

resource "mysql_database" "fun_db" {
  name = "fun"
}

resource "mysql_user" "fun_user" {
  user                = "fun"
  host                = "%"
  plaintext_password  = "fun123"
}

resource "mysql_grant" "fun_grant" {
  user        = "${mysql_user.fun_user.user}"
  host        = "${mysql_user.fun_user.host}"
  database    = "${mysql_database.fun_db.name}"
  privileges  = ["ALL"]
}

I abridged the aws_db_instance resource because I don't believe it's relevant, and simply used bogus strings for the DB, users and passwords, but the resources are as simple in my code as they are shown here.

The code above works fine. However, today, I found out I didn't need to manage the RDS endpoint because the DBA team "owns" these things and would simply set up the endpoint and provide me with credentials. So I deleted the above bits from my TF code and ran terraform apply. At that time, I was asked to provide values for provider.mysql.endpoint and provider.mysql.username.

I tried to leave them blank (since they were no longer applicable), but TF said:

$ terraform apply
provider.mysql.endpoint
  Enter a value:

provider.mysql.username
  Enter a value:

Error: provider.mysql: Endpoint must not be an empty string

Error: provider.mysql: Username must not be an empty string

I tried filling in bogus values just to get past it, but TF also did not like that because it couldn't connect to the bogus endpoint I provided.

I then deleted the contents of /.terraform/modules/ and /.terraform/modules/darwin_amd64/terraform-provider-mysql_v1.1.0_x4, then ran terraform init, and it reinstalled the mysql module. Again, the code calling the mysql provider and associated resources was gone at that point.

I triple, quadruple checked that I had no other mention of provider "mysql" {} in my code. I knew I didn't, because I've never had to use this provider anywhere, so the instance I deleted was the only one, so this was indeed nowhere else.

I figured then that something might be in my state file, so I did this:

$ terraform state rm mysql_database.fun_db
$ terraform state rm mysql_user.fun_user
$ terraform state rm mysql_grant.fun_grant

I keep my state file in an AWS S3 remote, if it matters.

Only after doing this was I able to run apply without issue, and everything was normal after that.

Again, I don't know if that's actually normal behavior when dealing with providers, and I've only ever dealt with the one provider (AWS), so deleting a provider from my code is not something I've ever done until today.

Expected Behavior

terraform apply removes resources that I removed from my code.

Actual Behavior

See above for details, but TF asked me to configure the mysql provider when running apply even though the code was gone.

Steps to Reproduce

  1. Set up the mysql provider to connect to a MySQL instance and set up some resources (db, user, grant, whatever -- I wouldn't think that matters).
  2. terraform apply
  3. Remove the provider "mysql" {} and mysql_... bits from the code you just ran.
  4. terraform apply

Let me know if you have any questions. Obviously, not a big deal, and maybe that's working as intended. Thought I'd report it just in case.

joestump commented 6 years ago

I don't believe TF will let you remove resources and providers in the same apply run as it needs the provider to remove said resources.

kennethgds commented 5 years ago

I had to deal with the exact same situation. This one definitely did the trick, As @fabiendelpierre mentioned

$ terraform state rm

But it's a pain when you have to delete quite a long list of grants and users associated with a single environment. I wonder if there's an option like this for such a use,

$ terraform state rm mysql_user.* $ terraform state rm mysql_grant.*

So that it can find all the resources that starts with this common attribute and deletes the rest, marked by an *.

deiga commented 4 years ago

@kennethgds Using some shell magic this can be solved quite nicely: terraform state list | grep mysql | while line -r read; do terraform state rm $line; done

(I did not verify this, but this should be fairly close to the answer)