diff --git a/examples/python/documentation/functions.py b/examples/python/documentation/functions.py
index fb6a067636..b7e9ac13ac 100644
--- a/examples/python/documentation/functions.py
+++ b/examples/python/documentation/functions.py
@@ -2,37 +2,50 @@
# SPDX-License-Identifier: MPL-2.0
from constructs import Construct
-from cdktf import TerraformStack, App, TerraformVariable, Token
+from cdktf import Op, TerraformStack, TerraformVariable, Token
+
# DOCS_BLOCK_START:functions-usage-example
from cdktf import Fn, TerraformOutput
from imports.aws.provider import AwsProvider
from imports.aws.data_aws_availability_zones import DataAwsAvailabilityZones
# DOCS_BLOCK_END:functions-usage-example
+from imports.aws.instance import Instance
+
class FunctionsStack(TerraformStack):
def __init__(self, scope: Construct, id: str):
super().__init__(scope, id)
- AwsProvider(self, "aws",
+ AwsProvider(self, "aws",
region="us-east-1"
)
# DOCS_BLOCK_START:functions-usage-example
-
zones = DataAwsAvailabilityZones(self, 'zones',
- state="available",
- )
+ state="available",
+ )
TerraformOutput(self, 'first-zone',
value=Fn.element(zones.names, 0)
)
-
# DOCS_BLOCK_END:functions-usage-example
+ # DOCS_BLOCK_START:functions-conditional
+ Instance(
+ self,
+ 'web',
+ ami='ami-2757f631',
+ count=Token.as_number(
+ Fn.conditional(Op.eq(Token.as_any('terraform.workspace'), 'prod'), 2, 1)
+ ),
+ instance_type='t2.micro',
+ )
+ # DOCS_BLOCK_END:functions-conditional
+
# INTERNAL NOTE: Due to an JSII bug, we have to pass the variable as a string_value in Python
# We can remove it, once https://github.com/aws/jsii/pull/4209 is released
# DOCS_BLOCK_START:functions-lookup
v = TerraformVariable(self, "complex-object",
- type = 'object({users: list(object({name: string}))})',
+ type='object({users: list(object({name: string}))})',
)
TerraformOutput(self, 'users',
value=Fn.lookup(v.string_value, "users")
@@ -50,4 +63,3 @@ def __init__(self, scope: Construct, id: str):
value=Fn.raw_string('${TEMPLATE}')
)
# DOCS_BLOCK_END:functions-raw-string
-
diff --git a/examples/typescript/documentation/functions.ts b/examples/typescript/documentation/functions.ts
index b339663077..c56277ccda 100644
--- a/examples/typescript/documentation/functions.ts
+++ b/examples/typescript/documentation/functions.ts
@@ -5,12 +5,19 @@ import { TerraformStack, TerraformVariable } from "cdktf";
import { Construct } from "constructs";
import { AwsProvider } from "@cdktf/provider-aws/lib/aws-provider";
// DOCS_BLOCK_END:functions
+// DOCS_BLOCK_START:functions-conditional
+import { Token } from "cdktf";
+import { Instance } from "@cdktf/provider-aws/lib/instance";
+// DOCS_BLOCK_END:functions-conditional
+// DOCS_BLOCK_START:functions-conditional,operators,functions,functions-raw
+import { Fn } from "cdktf";
+// DOCS_BLOCK_END:functions-conditional,operators,functions,functions-raw
// DOCS_BLOCK_START:operators,functions,functions-raw
-import { Fn, TerraformOutput } from "cdktf";
+import { TerraformOutput } from "cdktf";
// DOCS_BLOCK_END:operators,functions,functions-raw
-// DOCS_BLOCK_START:operators,functions-raw
+// DOCS_BLOCK_START:functions-conditional,operators,functions-raw
import { Op } from "cdktf";
-// DOCS_BLOCK_END:operators,functions-raw
+// DOCS_BLOCK_END:functions-conditional,operators,functions-raw
// DOCS_BLOCK_START:functions-raw,functions
import { DataAwsAvailabilityZones } from "@cdktf/provider-aws/lib/data-aws-availability-zones";
// DOCS_BLOCK_END:functions-raw,functions
@@ -37,6 +44,16 @@ export class FunctionsStack extends TerraformStack {
});
// DOCS_BLOCK_END:functions
+ // DOCS_BLOCK_START:functions-conditional
+ new Instance(this, "web", {
+ ami: "ami-2757f631",
+ count: Token.asNumber(
+ Fn.conditional(Op.eq(Token.asAny("terraform.workspace"), "prod"), 2, 1),
+ ),
+ instanceType: "t2.micro",
+ });
+ // DOCS_BLOCK_END:functions-conditional
+
// DOCS_BLOCK_START:functions-lookup
const v = new TerraformVariable(this, "complex_object", {
type: "object({users: list(object({name: string}))})",
diff --git a/website/docs/cdktf/concepts/functions.mdx b/website/docs/cdktf/concepts/functions.mdx
index 931f9615cc..a5638bd0d0 100644
--- a/website/docs/cdktf/concepts/functions.mdx
+++ b/website/docs/cdktf/concepts/functions.mdx
@@ -36,7 +36,8 @@ The `element` function gets the first element from the list of Availability Zone
import { TerraformStack, TerraformVariable } from "cdktf";
import { Construct } from "constructs";
import { AwsProvider } from "@cdktf/provider-aws/lib/aws-provider";
-import { Fn, TerraformOutput } from "cdktf";
+import { Fn } from "cdktf";
+import { TerraformOutput } from "cdktf";
import { DataAwsAvailabilityZones } from "@cdktf/provider-aws/lib/data-aws-availability-zones";
export class FunctionsStack extends TerraformStack {
constructor(scope: Construct, id: string) {
@@ -79,15 +80,13 @@ import imports.aws.data_aws_availability_zones.DataAwsAvailabilityZonesConfig;
from cdktf import Fn, TerraformOutput
from imports.aws.provider import AwsProvider
from imports.aws.data_aws_availability_zones import DataAwsAvailabilityZones
-
zones = DataAwsAvailabilityZones(self, 'zones',
- state="available",
- )
+ state="available",
+ )
TerraformOutput(self, 'first-zone',
value=Fn.element(zones.names, 0)
)
-
```
```csharp
@@ -159,6 +158,15 @@ func NewFunctionsStack(scope constructs.Construct, name string) cdktf.TerraformS
## Special functions
+### Conditional Expressions
+
+The ternary [conditional expression](/terraform/language/expressions/conditionals) is supported in CDKTF as a function. Its first argument for the condition or predicate is usually an [operator](/terraform/cdktf/concepts/functions#operators) such as `Op.eq()` to ensure a runtime comparison. Programming language operators like `==` will be evaluated at synthesis time and the result hardcoded into the generated JSON or HCL. Depending on usage, output and inputs may need their [Token](/terraform/cdktf/concepts/tokens) types specified.
+
+
+
+
+
+
### Property Access Helpers
To access nested properties from untyped objects or other datasources that return a dynamic datatype, use the Terraform function `lookup` or, for nested access, the function "Fn.lookupNested()" which is a function offered by CDKTF that allows to avoid nesting `Fn.lookup` calls.
@@ -169,6 +177,8 @@ To access nested properties from untyped objects or other datasources that retur
+
+
```ts
const v = new TerraformVariable(this, "complex_object", {
type: "object({users: list(object({name: string}))})",
@@ -181,7 +191,7 @@ new TerraformOutput(this, "first_user_name", {
```python
v = TerraformVariable(self, "complex-object",
- type = 'object({users: list(object({name: string}))})',
+ type='object({users: list(object({name: string}))})',
)
TerraformOutput(self, 'users',
value=Fn.lookup(v.string_value, "users")
@@ -230,6 +240,8 @@ cdktf.NewTerraformOutput(stack, jsii.String("first-user-name"), &cdktf.Terraform
})
```
+
+
### Raw string helper
Another helper function offered by CDKTF is `Fn.rawString` which can be used to escape raw strings that contain characters that CDKTF or Terraform would try to interpret otherwise.
@@ -240,6 +252,8 @@ Another helper function offered by CDKTF is `Fn.rawString` which can be used to
+
+
```ts
new TerraformOutput(this, "quotes", {
value: Fn.rawString(`"b"`),
@@ -287,6 +301,8 @@ cdktf.NewTerraformOutput(stack, jsii.String("template"), &cdktf.TerraformOutputC
})
```
+
+
## Operators
Use the `Op` object to include operators like `!`, `+`, and `-`.
@@ -298,7 +314,8 @@ Use the `Op` object to include operators like `!`, `+`, and `-`.
```ts
-import { Fn, TerraformOutput } from "cdktf";
+import { Fn } from "cdktf";
+import { TerraformOutput } from "cdktf";
import { Op } from "cdktf";
const zones = new DataAwsAvailabilityZones(this, "zones", {
@@ -360,7 +377,8 @@ It is also possible to use all built-in Terraform functions without using CDKTF'
```ts
-import { Fn, TerraformOutput } from "cdktf";
+import { Fn } from "cdktf";
+import { TerraformOutput } from "cdktf";
import { Op } from "cdktf";
import { DataAwsAvailabilityZones } from "@cdktf/provider-aws/lib/data-aws-availability-zones";
diff --git a/website/docs/cdktf/concepts/tokens.mdx b/website/docs/cdktf/concepts/tokens.mdx
index 17c773d7ca..004a662def 100644
--- a/website/docs/cdktf/concepts/tokens.mdx
+++ b/website/docs/cdktf/concepts/tokens.mdx
@@ -21,7 +21,7 @@ You may need to use Tokens for:
- [Module outputs](/terraform/cdktf/concepts/modules) for boolean, string, lists, maps, and other complex types.
- Resource attributes (such as `id`).
- Terraform outputs based on resource attributes.
-- Using Terraforms `null` type.
+- Using Terraform's `null` type and [terraform.workspace](/terraform/language/state/workspaces#current-workspace-interpolation).
### Example
@@ -216,3 +216,51 @@ cdktf.Token_NullValue()
```
+
+### Using `terraform.workspace`
+
+In the code below, the outer `Token.as_number()` avoids:
+
+> TypeError: type of argument count must be one of (int, float, cdktf.TerraformCount, NoneType); got jsii.\_reference_map.InterfaceDynamicProxy instead
+
+The inner `Token.as_any()` avoids generating extra quotes `"terraform.workspace"` and extra dollar signs `"$${terraform.workspace}"`.
+
+
+
+
+
+```python
+Instance(
+ self,
+ 'web',
+ ami='ami-2757f631',
+ count=Token.as_number(
+ Fn.conditional(Op.eq(Token.as_any('terraform.workspace'), 'prod'), 2, 1)
+ ),
+ instance_type='t2.micro',
+)
+```
+
+```ts
+import { Token } from "cdktf";
+import { Instance } from "@cdktf/provider-aws/lib/instance";
+import { Fn } from "cdktf";
+import { Op } from "cdktf";
+new Instance(this, "web", {
+ ami: "ami-2757f631",
+ count: Token.asNumber(
+ Fn.conditional(Op.eq(Token.asAny("terraform.workspace"), "prod"), 2, 1),
+ ),
+ instanceType: "t2.micro",
+});
+```
+
+```terraform
+resource "aws_instance" "web" {
+ ami = "ami-2757f631"
+ count = (terraform.workspace == "prod") ? 2 : 1
+ instance_type = "t2.micro"
+}
+```
+
+