configs/configupgrade: Fix up uses of the .count pseudo-attribute
Terraform 0.11 and prior had an odd special case where a resource attribute access for "count" would be resolved as the count for the whole resource, rather than as an attribute of an individual instance as for all other attributes. Because Terraform 0.12 makes test_instance.foo appear as a list when count is set (so it can be used in other expressions), it's no longer possible to have an attribute in that position: lists don't have attributes. Fortunately we don't really need that special case anymore since it doesn't do anything we can't now do with the length(...) function. This upgrade rule, then, detects references like test_instance.foo.count and rewrites to length(test_instance.foo). As a special case, if test_instance.foo doesn't have "count" set then it just rewrites as the constant 1, which mimics what would've happened in that case in Terraform 0.11.
This commit is contained in:
parent
b3cb94a929
commit
dd43926761
|
@ -0,0 +1,29 @@
|
|||
resource "test_instance" "one" {
|
||||
}
|
||||
|
||||
resource "test_instance" "many" {
|
||||
count = 2
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "one" {
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "many" {
|
||||
count = 2
|
||||
}
|
||||
|
||||
output "managed_one" {
|
||||
value = "${test_instance.one.count}"
|
||||
}
|
||||
|
||||
output "managed_many" {
|
||||
value = "${test_instance.many.count}"
|
||||
}
|
||||
|
||||
output "data_one" {
|
||||
value = "${data.terraform_remote_state.one.count}"
|
||||
}
|
||||
|
||||
output "data_many" {
|
||||
value = "${data.terraform_remote_state.many.count}"
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
resource "test_instance" "one" {
|
||||
}
|
||||
|
||||
resource "test_instance" "many" {
|
||||
count = 2
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "one" {
|
||||
}
|
||||
|
||||
data "terraform_remote_state" "many" {
|
||||
count = 2
|
||||
}
|
||||
|
||||
output "managed_one" {
|
||||
value = 1
|
||||
}
|
||||
|
||||
output "managed_many" {
|
||||
value = length(test_instance.many)
|
||||
}
|
||||
|
||||
output "data_one" {
|
||||
value = 1
|
||||
}
|
||||
|
||||
output "data_many" {
|
||||
value = length(data.terraform_remote_state.many)
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
terraform {
|
||||
required_version = ">= 0.12"
|
||||
}
|
|
@ -224,6 +224,44 @@ Value:
|
|||
// here so we can normalize and introduce some newer syntax where it's
|
||||
// safe to do so.
|
||||
parts := strings.Split(tv.Name, ".")
|
||||
|
||||
// First we need to deal with the .count pseudo-attributes that 0.11 and
|
||||
// prior allowed for resources. These no longer exist, because they
|
||||
// don't do anything we can't do with the length(...) function.
|
||||
if len(parts) > 0 {
|
||||
var rAddr addrs.Resource
|
||||
switch parts[0] {
|
||||
case "data":
|
||||
if len(parts) == 4 && parts[3] == "count" {
|
||||
rAddr.Mode = addrs.DataResourceMode
|
||||
rAddr.Type = parts[1]
|
||||
rAddr.Name = parts[2]
|
||||
}
|
||||
default:
|
||||
if len(parts) == 3 && parts[2] == "count" {
|
||||
rAddr.Mode = addrs.ManagedResourceMode
|
||||
rAddr.Type = parts[0]
|
||||
rAddr.Name = parts[1]
|
||||
}
|
||||
}
|
||||
|
||||
// We need to check if the thing being referenced is actually an
|
||||
// existing resource, because other three-part traversals might
|
||||
// coincidentally end with "count".
|
||||
if hasCount, exists := an.ResourceHasCount[rAddr]; exists {
|
||||
if hasCount {
|
||||
buf.WriteString("length(")
|
||||
buf.WriteString(rAddr.String())
|
||||
buf.WriteString(")")
|
||||
} else {
|
||||
// If the resource does not have count, the .count
|
||||
// attr would've always returned 1 before.
|
||||
buf.WriteString("1")
|
||||
}
|
||||
break Value
|
||||
}
|
||||
}
|
||||
|
||||
parts = upgradeTraversalParts(parts, an) // might add/remove/change parts
|
||||
first, remain := parts[0], parts[1:]
|
||||
buf.WriteString(first)
|
||||
|
|
Loading…
Reference in New Issue