Is there an existing issue for this?
What version of the Terraform provider are you using?
1.21.3
What version of the Terraform CLI are you using?
v1.14.3
What type of issue are you facing
bug report
Describe the bug
Every terraform apply that creates a btp_subaccount_destination_generic resource fails with the error below when destination_configuration is assigned a value derived from a Terraform input variable — regardless of whether for_each, a child module, or a single isolated resource is used.
Error: Provider produced inconsistent result after apply
When applying changes to btp_subaccount_destination_generic.<name>,
provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
new value: .destination_configuration: inconsistent values for sensitive attribute.
This is a bug in the provider, which should be reported in the provider's own issue tracker.
The bug is confirmed to affect all of the following resource forms:
btp_subaccount_destination_generic — single resource, variable-derived config
btp_subaccount_destination_generic — for_each in root module, variable-derived config
module.<name>.btp_subaccount_destination_generic — child module call, variable-derived config
Expected Behavior
terraform apply should complete successfully after creating a btp_subaccount_destination_generic resource, even when destination_configuration is derived from an input variable.
The provider should declare destination_configuration (or the credential sub-fields within it) as WriteOnly attributes — the correct semantic for fields that are write-only at the API level. WriteOnly attributes are excluded from Terraform's post-apply consistency check.
Steps To Reproduce
1. Execute terraform init
2. Execute terraform apply with the following configuration
variables.tf:
variable "subaccount_id" {
type = string
default = "<your-subaccount-id>"
}
variable "test_destination_config" {
description = "Single destination configuration for isolation testing."
type = map(string)
default = {
Name = "httpbin-no-auth-test-config"
Type = "HTTP"
URL = "https://httpbin.org"
ProxyType = "Internet"
Authentication = "NoAuthentication"
Description = "Isolation test — single var, no for_each"
}
}
variable "destinations" {
description = "Map of destinations to manage."
type = map(object({
name = string
service_instance_id = optional(string)
configuration = map(string)
}))
}
destinations.tfvars.json:
{
"destinations": {
"httpbin-basic-auth-jkey": {
"name": "httpbin-basic-auth-mod-jkey",
"service_instance_id": null,
"configuration": {
"Name": "httpbin-basic-auth-mod-jkey",
"Type": "HTTP",
"URL": "https://httpbin.org/basic-auth/user/passwd",
"ProxyType": "Internet",
"Authentication": "BasicAuthentication",
"User": "user",
"Password": "passwd",
"Description": "HTTP destination managed by module — BasicAuthentication"
}
},
"httpbin-no-auth-jkey": {
"name": "httpbin-no-auth-mod-jkey",
"service_instance_id": null,
"configuration": {
"Name": "httpbin-no-auth-mod-jkey",
"Type": "HTTP",
"URL": "https://httpbin.org",
"ProxyType": "Internet",
"Authentication": "NoAuthentication",
"Description": "HTTP destination managed by module — NoAuthentication"
}
},
"httpbin-basic-auth-instance-jkey": {
"name": "httpbin-basic-auth-instance-mod-jkey",
"service_instance_id": "ac9be7e3-27ed-488d-911b-XXXXXXXXXXXX",
"configuration": {
"Name": "httpbin-basic-auth-instance-mod-jkey",
"Type": "HTTP",
"URL": "https://httpbin.org/basic-auth/user/passwd",
"ProxyType": "Internet",
"Authentication": "BasicAuthentication",
"User": "user",
"Password": "passwd",
"Description": "HTTP destination managed by module — BasicAuthentication at instance level"
}
}
},
"destinations_module": {
"httpbin-basic-auth-jkey": {
"name": "httpbin-basic-auth-mod-module-jkey",
"service_instance_id": null,
"configuration": {
"Name": "httpbin-basic-auth-mod-module-jkey",
"Type": "HTTP",
"URL": "https://httpbin.org/basic-auth/user/passwd",
"ProxyType": "Internet",
"Authentication": "BasicAuthentication",
"User": "user",
"Password": "passwd",
"Description": "HTTP destination managed by module — BasicAuthentication"
}
},
"httpbin-no-auth-jkey": {
"name": "httpbin-no-auth-mod-module-jkey",
"service_instance_id": null,
"configuration": {
"Name": "httpbin-no-auth-mod-module-jkey",
"Type": "HTTP",
"URL": "https://httpbin.org",
"ProxyType": "Internet",
"Authentication": "NoAuthentication",
"Description": "HTTP destination managed by module — NoAuthentication"
}
},
"httpbin-basic-auth-instance-jkey": {
"name": "httpbin-basic-auth-instance-mod-module-jkey",
"service_instance_id": "ac9be7e3-27ed-488d-911b-XXXXXXXXXXXX",
"configuration": {
"Name": "httpbin-basic-auth-instance-mod-module-jkey",
"Type": "HTTP",
"URL": "https://httpbin.org/basic-auth/user/passwd",
"ProxyType": "Internet",
"Authentication": "BasicAuthentication",
"User": "user",
"Password": "passwd",
"Description": "HTTP destination managed by module — BasicAuthentication at instance level"
}
}
}
}
main.tf — isolation test (single resource, no for_each):
resource "btp_subaccount_destination_generic" "managed_single_test" {
subaccount_id = var.subaccount_id
destination_configuration = jsonencode(var.test_destination_config)
}
main.tf — for_each in root module and child module call:
locals {
destinations_managed = {
for key, dest in var.destinations :
"${var.subaccount_id},${dest.name}" => {
subaccount_id = var.subaccount_id
name = dest.name
service_instance_id = dest.service_instance_id
configuration = dest.configuration
}
}
destinations_managed_module = {
for key, dest in var.destinations_module :
"${var.subaccount_id},${dest.name}-module" => {
subaccount_id = var.subaccount_id
name = "${dest.name}-module"
service_instance_id = dest.service_instance_id
configuration = dest.configuration
}
}
}
# Root module — for_each
resource "btp_subaccount_destination_generic" "managed_root_working" {
for_each = local.destinations_managed
subaccount_id = each.value.subaccount_id
service_instance_id = each.value.service_instance_id
destination_configuration = jsonencode(each.value.configuration)
}
# Child module — for_each
module "btp-destination-generic-module-issue" {
source = "./modules/btp-destination-generic"
for_each = local.destinations_managed_module
destination = each.value
providers = { btp = btp }
}
Result: Apply fails on every CREATE with the error below. All 7 affected resources are tainted in state and will fail again on the next apply — the error recurs on every subsequent terraform apply.
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to btp_subaccount_destination_generic.managed_single_test,
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to btp_subaccount_destination_generic.managed_root_working["b80eac86-...,httpbin-no-auth-mod-jkey"],
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to btp_subaccount_destination_generic.managed_root_working["b80eac86-...,httpbin-basic-auth-mod-jkey"],
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to btp_subaccount_destination_generic.managed_root_working["b80eac86-...,httpbin-basic-auth-instance-mod-jkey,ac9be7e3-..."],
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to module.btp-destination-generic-module-issue["b80eac86-...,httpbin-no-auth-mod-module-jkey-module"].btp_subaccount_destination_generic.destination_generic,
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to module.btp-destination-generic-module-issue["b80eac86-...,httpbin-basic-auth-mod-module-jkey-module"].btp_subaccount_destination_generic.destination_generic,
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
╷
│ Error: Provider produced inconsistent result after apply
│
│ When applying changes to module.btp-destination-generic-module-issue["b80eac86-...,httpbin-basic-auth-instance-mod-module-jkey-module,ac9be7e3-..."].btp_subaccount_destination_generic.destination_generic,
│ provider "provider[\"registry.terraform.io/sap/btp\"]" produced an unexpected
│ new value: .destination_configuration: inconsistent values for sensitive attribute.
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
╵
3. Replace the variable reference with a hardcoded literal
resource "btp_subaccount_destination_generic" "test" {
subaccount_id = var.subaccount_id
destination_configuration = jsonencode({
Name = "httpbin-no-auth-test"
Type = "HTTP"
URL = "https://httpbin.org"
ProxyType = "Internet"
Authentication = "NoAuthentication"
})
}
Result: Apply succeeds. No error.
Tested expression forms
| Expression |
Result |
jsonencode(var.X) where X = map(string) |
❌ fails |
jsonencode(var.X.configuration) nested inside map(object) |
❌ fails |
var.X where X = string (pre-encoded JSON, no jsonencode) |
❌ fails |
jsonencode({ hardcoded literal }) |
✅ succeeds |
Reproduced with Authentication = "NoAuthentication" (no credential fields), which rules out credential fields as the sole trigger. The determining factor is that the value is variable-derived.
Attempted workarounds (none resolved the error)
lifecycle { ignore_changes = [destination_configuration] } — does not affect the post-apply consistency check. Only suppresses plan-time diffs. The error is raised after apply, not during planning.
nonsensitive(jsonencode(var.X)) — no effect. The consistency check operates on the provider schema-level sensitive flag, not the Terraform expression sensitivity.
configuration = string (pre-encoded JSON in .tfvars, no jsonencode()) — still fails. Eliminates jsonencode() as a contributing factor.
- Moving
jsonencode() into a child module — still fails with the same error on every CREATE.
User's Role Collections
Add screenshots to help explain your problem
Additional context
Provider schema definition
The destination_configuration attribute is declared in the provider schema as:
Required
destination_configuration (String, Sensitive) The configuration parameters for the destination.
Even though there's a comment that we don't know how to interpret:
"Password" = "YourPassword" # Property required, but do not maintain it on your IaC repository. Keep it blank!
This declaration (Sensitive) may be the direct cause of the failure.
The Password field is required by the BTP Destination Service API, but should not be stored in source control. How can we handle this in an IaC scenario?
Leave the Password field blank in the Terraform configuration and then update it manually in the BTP cockpit after creation? Or is there a recommended approach for managing this securely within Terraform?
How can we handle the imports and the passwords?
Is there an existing issue for this?
What version of the Terraform provider are you using?
1.21.3
What version of the Terraform CLI are you using?
v1.14.3
What type of issue are you facing
bug report
Describe the bug
Every
terraform applythat creates abtp_subaccount_destination_genericresource fails with the error below whendestination_configurationis assigned a value derived from a Terraform input variable — regardless of whetherfor_each, a child module, or a single isolated resource is used.The bug is confirmed to affect all of the following resource forms:
btp_subaccount_destination_generic— single resource, variable-derived configbtp_subaccount_destination_generic—for_eachin root module, variable-derived configmodule.<name>.btp_subaccount_destination_generic— child module call, variable-derived configExpected Behavior
terraform applyshould complete successfully after creating abtp_subaccount_destination_genericresource, even whendestination_configurationis derived from an input variable.The provider should declare
destination_configuration(or the credential sub-fields within it) asWriteOnlyattributes — the correct semantic for fields that are write-only at the API level.WriteOnlyattributes are excluded from Terraform's post-apply consistency check.Steps To Reproduce
1. Execute
terraform init2. Execute
terraform applywith the following configurationvariables.tf:
destinations.tfvars.json:
{ "destinations": { "httpbin-basic-auth-jkey": { "name": "httpbin-basic-auth-mod-jkey", "service_instance_id": null, "configuration": { "Name": "httpbin-basic-auth-mod-jkey", "Type": "HTTP", "URL": "https://httpbin.org/basic-auth/user/passwd", "ProxyType": "Internet", "Authentication": "BasicAuthentication", "User": "user", "Password": "passwd", "Description": "HTTP destination managed by module — BasicAuthentication" } }, "httpbin-no-auth-jkey": { "name": "httpbin-no-auth-mod-jkey", "service_instance_id": null, "configuration": { "Name": "httpbin-no-auth-mod-jkey", "Type": "HTTP", "URL": "https://httpbin.org", "ProxyType": "Internet", "Authentication": "NoAuthentication", "Description": "HTTP destination managed by module — NoAuthentication" } }, "httpbin-basic-auth-instance-jkey": { "name": "httpbin-basic-auth-instance-mod-jkey", "service_instance_id": "ac9be7e3-27ed-488d-911b-XXXXXXXXXXXX", "configuration": { "Name": "httpbin-basic-auth-instance-mod-jkey", "Type": "HTTP", "URL": "https://httpbin.org/basic-auth/user/passwd", "ProxyType": "Internet", "Authentication": "BasicAuthentication", "User": "user", "Password": "passwd", "Description": "HTTP destination managed by module — BasicAuthentication at instance level" } } }, "destinations_module": { "httpbin-basic-auth-jkey": { "name": "httpbin-basic-auth-mod-module-jkey", "service_instance_id": null, "configuration": { "Name": "httpbin-basic-auth-mod-module-jkey", "Type": "HTTP", "URL": "https://httpbin.org/basic-auth/user/passwd", "ProxyType": "Internet", "Authentication": "BasicAuthentication", "User": "user", "Password": "passwd", "Description": "HTTP destination managed by module — BasicAuthentication" } }, "httpbin-no-auth-jkey": { "name": "httpbin-no-auth-mod-module-jkey", "service_instance_id": null, "configuration": { "Name": "httpbin-no-auth-mod-module-jkey", "Type": "HTTP", "URL": "https://httpbin.org", "ProxyType": "Internet", "Authentication": "NoAuthentication", "Description": "HTTP destination managed by module — NoAuthentication" } }, "httpbin-basic-auth-instance-jkey": { "name": "httpbin-basic-auth-instance-mod-module-jkey", "service_instance_id": "ac9be7e3-27ed-488d-911b-XXXXXXXXXXXX", "configuration": { "Name": "httpbin-basic-auth-instance-mod-module-jkey", "Type": "HTTP", "URL": "https://httpbin.org/basic-auth/user/passwd", "ProxyType": "Internet", "Authentication": "BasicAuthentication", "User": "user", "Password": "passwd", "Description": "HTTP destination managed by module — BasicAuthentication at instance level" } } } }main.tf — isolation test (single resource, no
for_each):main.tf —
for_eachin root module and child module call:Result: Apply fails on every CREATE with the error below. All 7 affected resources are tainted in state and will fail again on the next apply — the error recurs on every subsequent
terraform apply.3. Replace the variable reference with a hardcoded literal
Result: Apply succeeds. No error.
Tested expression forms
jsonencode(var.X)whereX = map(string)jsonencode(var.X.configuration)nested insidemap(object)var.XwhereX = string(pre-encoded JSON, no jsonencode)jsonencode({ hardcoded literal })Reproduced with
Authentication = "NoAuthentication"(no credential fields), which rules out credential fields as the sole trigger. The determining factor is that the value is variable-derived.Attempted workarounds (none resolved the error)
lifecycle { ignore_changes = [destination_configuration] }— does not affect the post-apply consistency check. Only suppresses plan-time diffs. The error is raised after apply, not during planning.nonsensitive(jsonencode(var.X))— no effect. The consistency check operates on the provider schema-levelsensitiveflag, not the Terraform expression sensitivity.configuration = string(pre-encoded JSON in.tfvars, nojsonencode()) — still fails. Eliminatesjsonencode()as a contributing factor.jsonencode()into a child module — still fails with the same error on every CREATE.User's Role Collections
Add screenshots to help explain your problem
Additional context
Provider schema definition
The
destination_configurationattribute is declared in the provider schema as:Required destination_configuration (String, Sensitive) The configuration parameters for the destination.Even though there's a comment that we don't know how to interpret:
This declaration (
Sensitive) may be the direct cause of the failure.The
Passwordfield is required by the BTP Destination Service API, but should not be stored in source control. How can we handle this in an IaC scenario?Leave the
Passwordfield blank in the Terraform configuration and then update it manually in the BTP cockpit after creation? Or is there a recommended approach for managing this securely within Terraform?How can we handle the imports and the passwords?