This ticket is a feature request for keeping an existing feature. :)
I appreciate that it's problematic for destroy-time provisioners to reference arbitrary resources. However, in my opinion TF 0.12.18 (https://github.com/hashicorp/terraform/pull/23559) goes a little bit too far in what it deprecates, so I'm hoping this can be tweaked a bit before the warnings become hard failures.
Terraform v0.12.18
+ provider.null v2.1.2
I'm using Terraform to provision some AWS resources, and along with those resources I also want to provision an object in another system I have, so that I can conveniently deploy it all at once and destroy it all at once.
I understand and acknowledge that the Best Way to do this would be a custom TF provider, but that level of time investment isn't practical for me at the moment. Since I already have scripts that deal with my custom object, I've been quite successful wrapping those scripts into a TF module using null_resource.
Here's a simplified example:
mymodule/module.tf:
variable "thing" {
type = string
}
resource "null_resource" "thing_maker" {
triggers = {
thing = var.thing
}
provisioner "local-exec" {
command = "./myscript add '${self.triggers.thing}'"
working_dir = path.module
}
provisioner "local-exec" {
when = destroy
command = "./myscript del '${self.triggers.thing}'"
working_dir = path.module
}
}
main.tf:
variable "thing1" {
default = "world"
}
module "thing1" {
source = "./mymodule"
thing = var.thing1
}
The meaningful parameters of the external object are handled correctly by embedding them in self.triggers, which is important because when I change var.thing the old null_resource remembers how to delete the _old_ external object. This works very well, except TF 0.12.18 complains that my use of path.module is deprecated:
$ terraform-0.12.18 apply -auto-approve
module.thing1.null_resource.thing_maker: Creating...
module.thing1.null_resource.thing_maker: Provisioning with 'local-exec'...
module.thing1.null_resource.thing_maker (local-exec): Executing: ["/bin/sh" "-c" "./myscript add 'world'"]
module.thing1.null_resource.thing_maker (local-exec): Hello world
module.thing1.null_resource.thing_maker: Creation complete after 0s [id=8149589692958343466]
Warning: External references from destroy provisioners are deprecated
on mymodule/module.tf line 18, in resource "null_resource" "thing_maker":
18: working_dir = path.module
Destroy-time provisioners and their connection configurations may only
reference attributes of the related resource, via 'self', 'count.index', or
'each.key'.
References to other resources during the destroy phase can cause dependency
cycles and interact poorly with create_before_destroy.
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
$ terraform-0.12.18 apply -auto-approve -var 'thing1=universe'
module.thing1.null_resource.thing_maker: Refreshing state... [id=8149589692958343466]
module.thing1.null_resource.thing_maker: Destroying... [id=8149589692958343466]
module.thing1.null_resource.thing_maker: Provisioning with 'local-exec'...
module.thing1.null_resource.thing_maker (local-exec): Executing: ["/bin/sh" "-c" "./myscript del 'world'"]
module.thing1.null_resource.thing_maker (local-exec): Goodbye world
module.thing1.null_resource.thing_maker: Destruction complete after 0s
module.thing1.null_resource.thing_maker: Creating...
module.thing1.null_resource.thing_maker: Provisioning with 'local-exec'...
module.thing1.null_resource.thing_maker (local-exec): Executing: ["/bin/sh" "-c" "./myscript add 'universe'"]
module.thing1.null_resource.thing_maker (local-exec): Hello universe
module.thing1.null_resource.thing_maker: Creation complete after 0s [id=4531342667248734256]
Warning: External references from destroy provisioners are deprecated
on mymodule/module.tf line 18, in resource "null_resource" "thing_maker":
18: working_dir = path.module
Destroy-time provisioners and their connection configurations may only
reference attributes of the related resource, via 'self', 'count.index', or
'each.key'.
References to other resources during the destroy phase can cause dependency
cycles and interact poorly with create_before_destroy.
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
$ terraform-0.12.18 destroy -auto-approve
module.thing1.null_resource.thing_maker: Refreshing state... [id=4531342667248734256]
module.thing1.null_resource.thing_maker: Destroying... [id=4531342667248734256]
module.thing1.null_resource.thing_maker: Provisioning with 'local-exec'...
module.thing1.null_resource.thing_maker (local-exec): Executing: ["/bin/sh" "-c" "./myscript del 'universe'"]
module.thing1.null_resource.thing_maker (local-exec): Goodbye universe
module.thing1.null_resource.thing_maker: Destruction complete after 0s
Warning: External references from destroy provisioners are deprecated
on mymodule/module.tf line 18, in resource "null_resource" "thing_maker":
18: working_dir = path.module
Destroy-time provisioners and their connection configurations may only
reference attributes of the related resource, via 'self', 'count.index', or
'each.key'.
References to other resources during the destroy phase can cause dependency
cycles and interact poorly with create_before_destroy.
Destroy complete! Resources: 1 destroyed.
Hypothetically, embedding path.module into triggers might suppress the warning, but that doesn't feel right; the path has nothing to do with the object's identity, and if somehow the path changed I wouldn't want it to recreate the object for that reason. (note: I have not studied in detail the actual contents of path.module in various scenarios, including if the module is sourced from git instead of just being a subdirectory).
AFAICT path.module fundamentally doesn't pose the same problem https://github.com/hashicorp/terraform/pull/23559 was intended to solve, and therefore I'd like to request that you consider exempting (i.e. allowing) it.
I suspect there might actually be a whole category of similar "references" that could more-or-less safely be allowed, but I'm not sure, and in any case this is the only one I'm actively relying on right now.
Seems to be the same problem seen here #3254
This comment more specifically: https://github.com/hashicorp/terraform/issues/3254#issuecomment-531502543
I think I'm running in a similar issue here:
resource "openstack_compute_instance_v2" "instance" {
...
provisioner "local-exec" {
when = destroy
command = "${path.module}/scripts/puppet_cert_clean.sh ${local.instance_prefix}.${var.instance_name}${format("%02d", count.index + 1)}"
}
}
If I get this right, the problem is about the local.instance_prefix:
locals {
instance_prefix = "${data.openstack_identity_auth_scope_v3.project.project_name}.${data.openstack_compute_availability_zones_v2.zones.names[0]}"
}
As there is no other way to automatically determine the OpenStack project name and availability zone, I'm not sure who to fix this and tend to support @dmrzzz statement :)
However, in my opinion TF 0.12.18 (#23559) goes a little bit too far in what it deprecates, so I'm hoping this can be tweaked a bit before the warnings become hard failures.
@jbardin Do you mind taking another look at this? I'm still getting the same warning after upgrading to 0.12.20.
Am I just doing unsupported things? What might be a better solution for my problem? I need the configured project (already done on the provider) within a module.
@baurmatt,
This issue is specially about allowing the path.module value to be used in a destroy provisioner. If you have other references to resources, locals, or variables you will continue to get a warning.
We use GitHub issues for tracking bugs and enhancements, rather than for questions. While we can sometimes help with certain simple problems here, it's better to use the community forum where there are more people ready to help
In my case, I'm using a local-exec provisioner that is triggered by "destroy" action on aws_instance resource.
provisioner "local-exec" {
when = destroy
command = "curl -X DELETE -s $API_URL$API_PATH$LOCATION/$SERVER_NAME -H \"apikey: $API_KEY\""
# continue on failure - in case of external instances not managed by Chef
on_failure = continue
environment = {
API_URL = var.cleanup_api_url
API_PATH = "/api/v1/vm/"
LOCATION = local.cleanup_api_location
SERVER_NAME = self.tags["Name"]
API_KEY = var.cleanup_api_key
}
}
terraform validate returns the following error
Warning: External references from destroy provisioners are deprecated
on 10-main.tf line 208, in resource "aws_instance" "instance":
208: environment = {
209: API_URL = var.cleanup_api_url
210: API_PATH = "/api/v1/vm/"
211: LOCATION = local.cleanup_api_location
212: SERVER_NAME = self.tags["Name"]
213: API_KEY = var.cleanup_api_key
214: }Destroy-time provisioners and their connection configurations may only
reference attributes of the related resource, via 'self', 'count.index', or
'each.key'.References to other resources during the destroy phase can cause dependency
cycles and interact poorly with create_before_destroy.(and 2 more similar warnings elsewhere)
Problem is, those variables and locals, which are used do not require any special dependency.
For example:
variable "cleanup_api_url" {
description = "Production API system API URL"
default = "https://example.com"
type = string
}
variable "cleanup_api_key" {
description = "API key used to perform cleanup of VM attributes in our other systems like DNS, IP reservation"
default = ""
type = string
}
# passed to module as variable
variable "domain" {
description = "AD domain name"
type = string
}
locals {
cleanup_api_location = var.domain == "some.local" ? "loc1" : var.domain == "other.local" ? "loc2" : "loc3"
}
We are currently on 0.12.13 terraform version and this works wonderfull, but we are trying to upgrade to the latest version (0.12.20 atm) and are perplexed with the warning that should not be considered one.
Do you see any other way that we could update our code in a non-breaking one?
We want to avoid using hardcoded values instead of variables
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
In my case, I'm using a local-exec provisioner that is triggered by "destroy" action on aws_instance resource.
terraform validatereturns the following errorProblem is, those variables and locals, which are used do not require any special dependency.
For example:
We are currently on 0.12.13 terraform version and this works wonderfull, but we are trying to upgrade to the latest version (0.12.20 atm) and are perplexed with the warning that should not be considered one.
Do you see any other way that we could update our code in a non-breaking one?
We want to avoid using hardcoded values instead of variables