Cannot delete an instance of module in Terraform which contains a provider

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Cannot delete an instance of module in Terraform which contains a provider



I have a module which contains resources for:



In one of my env directories I can have 0-N .tf files which is an instance of that module and each specify database name etc. So if I add another .tf file with a new name then a new database server with a database will be provisioned. All this works fine.



However, if I now delete an existing database module (one of the .tf files in my env directory) I run into issues. Terraform will now try to get the state of all the previously existing resources and since that specific provider (for that postgres server) now is gone terraform cannot get the state of the created postgres role, with the output a provider configuration block is required for all operations.



I understand why this happens but I cannot figure out how to solve this. I want to "dynamically" create (and remove) postgres servers with a database on them but this requires "dynamic" providers which then makes me get stuck on this.



Example of how it looks


resource "azurerm_postgresql_server" "postgresserver" {
name = "${var.db_name}-server"
location = "${var.location}"
resource_group_name = "${var.resource_group}"

sku = ["${var.vmSize}"]

storage_profile = ["${var.storage}"]

administrator_login = "psqladminun"
administrator_login_password = "${random_string.db-password.result}"
version = "${var.postgres_version}"
ssl_enforcement = "Disabled"
}

provider "postgresql" {
version = "0.1.0"
host = "${azurerm_postgresql_server.postgresserver.fqdn}"
port = 5432
database = "postgres"
username = "${azurerm_postgresql_server.postgresserver.administrator_login}@${azurerm_postgresql_server.postgresserver.name}".
password = "${azurerm_postgresql_server.postgresserver.administrator_login_password}"
}

resource "azurerm_postgresql_database" "db" {
name = "${var.db_name}"
resource_group_name = "${var.resource_group}"
server_name = "${azurerm_postgresql_server.postgresserver.name}"
charset = "UTF8"
collation = "English_United States.1252"
}

resource "postgresql_role" "role" {
name = "${random_string.user.result}"
login = true
connection_limit = 100
password = "${random_string.pass.result}"
create_role = true
create_database = true

depends_on = ["azurerm_postgresql_database.db"]
}



Above you see how we, in the module create a postgres server, postgres db and also a postgres role (where only the role utilizes the postgres provider). So if I now define an instance datadb.tf such as:


module "datadb" {
source = "../../modules/postgres"
db_name = "datadb"
resource_group = "${azurerm_resource_group.resource-group.name}"
location = "${azurerm_resource_group.resource-group.location}"
}



then it will be provisioned successfully. The issue is if I later on delete that same file (datadb.tf) then the planning fails because it will try to get the state of the postgres role without having the postgres provider present.
The postgres provider is only needed for the postgres role which will be destroyed as soon as the azure provider destroys the postgres db and postgres server, so the actual removal of that role is not necessary. Is there a way to tell terraform that "if this resource should be removed, you don't have to do anything because it will be removed dependent on being removed"? Or does anyone see any other solutions?



I hope my goal and issue is clear, thanks!





You might need to give more information here (and maybe a Minimal, Complete, and Verifiable example) because this doesn't match the behaviour that I see in that destroys should be fine because Terraform will work back through the dependency chain, removing the Postgres parts before removing the database server (assuming you are setting the postgres provider connection details to the interpolated output from the database server resource). On the other hand there is a known issue where the current Postgres provider chokes on the first plan/apply if the database instance doesn't already exist because it can't feature detect.
– ydaetskcoR
Jun 14 at 11:19







Hey! Thanks for that, I added example of how the module looks (only the necessary resources for this issue) and also how a file where we define an instance of that module looks. So the issue is adding that file, the applying it and provisioning it. And then later on, removing the file (with the desire for everything to be removed) causes issues because of terraform not able to getting the state of the postgres role because of no provider present.
– poppe
Jun 14 at 12:04





What version of the Postgres provider are you using?
– ydaetskcoR
Jun 14 at 12:06





So I think the issue is that the provider is not a part of the dependancy chain so it does just like you say, starts by removing the postgres role but at that point there's no provider present.
– poppe
Jun 14 at 12:06





"0.1.0", like it says in the snippet
– poppe
Jun 14 at 12:07




1 Answer
1



I think the only solution is a two-step solution, but I think it's still clean enough.
What I would do is have two files per database (name them how you want).


db-1-infra.tf
db-1-pgsql.tf



Put everything except your postgres resources in db-1-infra.tf


resource "azurerm_postgresql_server" "postgresserver" {
name = "${var.db_name}-server"
location = "${var.location}"
resource_group_name = "${var.resource_group}"

sku = ["${var.vmSize}"]

storage_profile = ["${var.storage}"]

administrator_login = "psqladminun"
administrator_login_password = "${random_string.db-password.result}"
version = "${var.postgres_version}"
ssl_enforcement = "Disabled"
}

provider "postgresql" {
version = "0.1.0"
host = "${azurerm_postgresql_server.postgresserver.fqdn}"
port = 5432
database = "postgres"
username = "${azurerm_postgresql_server.postgresserver.administrator_login}@${azurerm_postgresql_server.postgresserver.name}".
password = "${azurerm_postgresql_server.postgresserver.administrator_login_password}"
}

resource "azurerm_postgresql_database" "db" {
name = "${var.db_name}"
resource_group_name = "${var.resource_group}"
server_name = "${azurerm_postgresql_server.postgresserver.name}"
charset = "UTF8"
collation = "English_United States.1252"
}



Put your PostgreSQL resources in db-1-pgsql.tf


resource "postgresql_role" "role" {
name = "${random_string.user.result}"
login = true
connection_limit = 100
password = "${random_string.pass.result}"
create_role = true
create_database = true

depends_on = ["azurerm_postgresql_database.db"]



}



When you want to get rid of your database, first delete the file db-1-pgsql.tf and apply. Next, delete db-1-infra.tf and apply again.



The first step will destroy all postgres resources and free you up to run the second step, which will remove the postgres provider for that database.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

2uwz6ovxjB8D WqoTofBsVQMjG2GF Zd4,j6Sio D34jo27 LPzMMj 86gBNQ,tZMxl 0r4tbNl g1B
lOyx4o6wP6PEhK2Ih DZ,qVDwjQuDo lnk7Ews13lcpG7qeNly6OaFN,xY9n3rBq1H,jjqnFwav 3ADlfcqKXI,gZ7Bqxdp,PV jS,9

Popular posts from this blog

Makefile test if variable is not empty

Visual Studio Code: How to configure includePath for better IntelliSense results

Will Oldham