diff --git a/internal/lang/funcs/descriptions.go b/internal/lang/funcs/descriptions.go
index 6a96394f3906..a8cb3bfa63f5 100644
--- a/internal/lang/funcs/descriptions.go
+++ b/internal/lang/funcs/descriptions.go
@@ -233,6 +233,10 @@ var DescriptionList = map[string]descriptionEntry{
Description: "`index` finds the element index for a given value in a list.",
ParamDescription: []string{"", ""},
},
+ "issensitive": {
+ Description: "`issensitive` takes a value and returns a boolean indicating if the value is sensitive.",
+ ParamDescription: []string{""},
+ },
"join": {
Description: "`join` produces a string by concatenating together all elements of a given list of strings with the given delimiter.",
ParamDescription: []string{
diff --git a/internal/lang/funcs/sensitive.go b/internal/lang/funcs/sensitive.go
index 97703a4f1326..b30e2fa579c3 100644
--- a/internal/lang/funcs/sensitive.go
+++ b/internal/lang/funcs/sensitive.go
@@ -58,6 +58,24 @@ var NonsensitiveFunc = function.New(&function.Spec{
},
})
+var IssensitiveFunc = function.New(&function.Spec{
+ Params: []function.Parameter{{
+ Name: "value",
+ Type: cty.DynamicPseudoType,
+ AllowUnknown: true,
+ AllowNull: true,
+ AllowMarked: true,
+ AllowDynamicType: true,
+ }},
+ Type: func(args []cty.Value) (cty.Type, error) {
+ return cty.Bool, nil
+ },
+ Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
+ s := args[0].HasMark(marks.Sensitive)
+ return cty.BoolVal(s), nil
+ },
+})
+
func Sensitive(v cty.Value) (cty.Value, error) {
return SensitiveFunc.Call([]cty.Value{v})
}
@@ -65,3 +83,7 @@ func Sensitive(v cty.Value) (cty.Value, error) {
func Nonsensitive(v cty.Value) (cty.Value, error) {
return NonsensitiveFunc.Call([]cty.Value{v})
}
+
+func Issensitive(v cty.Value) (cty.Value, error) {
+ return IssensitiveFunc.Call([]cty.Value{v})
+}
diff --git a/internal/lang/funcs/sensitive_test.go b/internal/lang/funcs/sensitive_test.go
index 96e647d05348..4a2b807f73fb 100644
--- a/internal/lang/funcs/sensitive_test.go
+++ b/internal/lang/funcs/sensitive_test.go
@@ -180,3 +180,75 @@ func TestNonsensitive(t *testing.T) {
})
}
}
+
+func TestIssensitive(t *testing.T) {
+ tests := []struct {
+ Input cty.Value
+ Sensitive bool
+ WantErr string
+ }{
+ {
+ cty.NumberIntVal(1).Mark(marks.Sensitive),
+ true,
+ ``,
+ },
+ {
+ cty.NumberIntVal(1),
+ false,
+ ``,
+ },
+ {
+ cty.DynamicVal.Mark(marks.Sensitive),
+ true,
+ ``,
+ },
+ {
+ cty.UnknownVal(cty.String).Mark(marks.Sensitive),
+ true,
+ ``,
+ },
+ {
+ cty.NullVal(cty.EmptyObject).Mark(marks.Sensitive),
+ true,
+ ``,
+ },
+ {
+ cty.NullVal(cty.String),
+ false,
+ ``,
+ },
+ {
+ cty.DynamicVal,
+ false,
+ ``,
+ },
+ {
+ cty.UnknownVal(cty.String),
+ false,
+ ``,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(fmt.Sprintf("issensitive(%#v)", test.Input), func(t *testing.T) {
+ got, err := Issensitive(test.Input)
+
+ if test.WantErr != "" {
+ if err == nil {
+ t.Fatal("succeeded; want error")
+ }
+ if got, want := err.Error(), test.WantErr; got != want {
+ t.Fatalf("wrong error\ngot: %s\nwant: %s", got, want)
+ }
+ return
+ } else if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+
+ if (got.True() && !test.Sensitive) || (got.False() && test.Sensitive) {
+ t.Errorf("wrong result \ngot: %#v\nwant: %#v", got, test.Sensitive)
+ }
+ })
+ }
+
+}
diff --git a/internal/lang/functions.go b/internal/lang/functions.go
index 337f3ff54fb9..10c72981a66b 100644
--- a/internal/lang/functions.go
+++ b/internal/lang/functions.go
@@ -103,6 +103,7 @@ func (s *Scope) Functions() map[string]function.Function {
"rsadecrypt": funcs.RsaDecryptFunc,
"sensitive": funcs.SensitiveFunc,
"nonsensitive": funcs.NonsensitiveFunc,
+ "issensitive": funcs.IssensitiveFunc,
"setintersection": stdlib.SetIntersectionFunc,
"setproduct": stdlib.SetProductFunc,
"setsubtract": stdlib.SetSubtractFunc,
@@ -301,6 +302,7 @@ func baseFunctions(baseDir string) map[string]function.Function {
"rsadecrypt": funcs.RsaDecryptFunc,
"sensitive": funcs.SensitiveFunc,
"nonsensitive": funcs.NonsensitiveFunc,
+ "issensitive": funcs.IssensitiveFunc,
"setintersection": stdlib.SetIntersectionFunc,
"setproduct": stdlib.SetProductFunc,
"setsubtract": stdlib.SetSubtractFunc,
diff --git a/internal/lang/functions_test.go b/internal/lang/functions_test.go
index 7add47b247ad..bdf1b16de73d 100644
--- a/internal/lang/functions_test.go
+++ b/internal/lang/functions_test.go
@@ -515,6 +515,13 @@ func TestFunctions(t *testing.T) {
},
},
+ "issensitive": {
+ {
+ `issensitive(1)`,
+ cty.False,
+ },
+ },
+
"join": {
{
`join(" ", ["Hello", "World"])`,
diff --git a/website/data/language-nav-data.json b/website/data/language-nav-data.json
index 5760c710bd86..be2c59026813 100644
--- a/website/data/language-nav-data.json
+++ b/website/data/language-nav-data.json
@@ -690,6 +690,10 @@
"title": "Type Conversion Functions",
"routes": [
{ "title": "can
", "href": "/language/functions/can" },
+ {
+ "title": "issensitive
",
+ "href": "/language/functions/issensitive"
+ },
{
"title": "nonsensitive
",
"href": "/language/functions/nonsensitive"
diff --git a/website/docs/language/functions/issensitive.mdx b/website/docs/language/functions/issensitive.mdx
new file mode 100644
index 000000000000..6647af1d442d
--- /dev/null
+++ b/website/docs/language/functions/issensitive.mdx
@@ -0,0 +1,27 @@
+---
+page_title: issensitive - Functions - Configuration Language
+description: The issensitive function true if the value passed is marked as sensitive
+---
+
+# `issensitive` Function
+
+-> **Note:** This function is only available in Terraform v1.8 and later.
+
+`issensitive` takes any value and returns true if Terraform
+treats it as sensitive, with the same meaning and behavior as for
+[sensitive input variables](/terraform/language/values/variables#suppressing-values-in-cli-output).
+
+If a value not marked as sensitive is passed the function returns false.
+
+See [`sensitive`](/terraform/language/functions/sensitive), [`nonsensitive`](/terraform/language/functions/nonsensitive), and [sensitive input variables](/terraform/language/values/variables#suppressing-values-in-cli-output) for more information on sensitive values.
+
+## Examples
+
+```
+> issensitive(sensitive("secret"))
+true
+> issensitive("hello")
+false
+> sensitive(var.my-var-with-sensitive-set-to-true)
+true
+```