Open alisdair opened 3 years ago
Honestly, the surprising part of this report for me was that the human-oriented report was able to distinguish sensitivity so granularly:
- os_profile { # forces replacement
- admin_username = "testadmin" -> null
- computer_name = "hostname" -> null
}
+ os_profile { # forces replacement
+ admin_password = (sensitive value)
+ admin_username = "testadmins"
+ computer_name = "hostnames"
+ custom_data = (known after apply)
}
Our mechanism for tracking dynamic sensitivity doesn't allow tracking nested sensitivity within sets, so I have to assume this is the effect of some other mechanism. I'd guess what's probably happening here is that the human-oriented diff renderer is ignoring dynamic value sensitivity altogether when rendering nested blocks -- in which case, it's disclosing values there that we'd normally conservatively consider to be sensitive -- but then the static schema for admin_password
comes to the rescue, because that capability predates our dynamic sensitivity tracking.
I think we'll have an interesting tradeoff to make here, since while in this particular case it's clear that the intent is only for admin_password
to be sensitive, if I'm understanding correctly then we're only accidentally matching that intent, as a result of ignoring the sensitivity mark on the os_profile
set. An un-nuanced read of the dynamic sensitivity design would say that the human-oriented diff output is the one misbehaving here, because it's showing admin_username
and computer_name
even though we accessed them through a sensitive set value.
The JSON renderer, on the other hand, is describing things as they actually are in the dynamic value. It'd be interesting to see if there's a symmetrical opposite "miss" here, where the JSON output disregards the static sensitivity flag in the schema; if so, just naively ignoring the sensitivity flag would cause us to not mark admin_password
as sensitive at all, which would also be inconsistent.
Another tricky part, though thankfully not as tricky, is that to properly represent what we saw in the human-oriented diff output here we'd need to be sure to include one element of after_sensitive.os_profile
for each element in after.os_profile
and ensure that the indices match up so that the consumer can actually correlate them even though sets are not naturally ordered. We'd choose an arbitrary but consistent order to use for all of the various array-based representations we include here, I suppose.
"after_sensitive": {
"os_profile": [
{
"admin_password": true
},
{
"admin_password": true
}
]
}
Terraform Version
Terraform Configuration Files
Expected Behavior
CLI output shows details about the
os_profile
block attribute values changing:To allow consumers of the JSON plan to do the same, the
after_sensitive
data should mark theadmin_password
in theos_profile
block as sensitive, like so:Actual Behavior
The entire
os_profile
block is marked sensitive:Steps to Reproduce
azurerm_virtual_machine
os_profile
blockterraform plan -out=saved.tfplan
terraform show -json saved.tfplan | jq '.resource_changes[] | select( .address == "azurerm_virtual_machine.test") | .change
Found by @brandonc.