> ## Documentation Index
> Fetch the complete documentation index at: https://cdktn.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tokens - CDK Terrain

> Tokens allow CDK Terrain to resolve programming language types to Terraform language syntax.

Tokens represent values that are unknown until Terraform (or OpenTofu) applies your configuration. For example, names of cloud resources are only assigned upon creation.

Some attributes specified using CDK Terrain (CDKTN) may not directly map to the values required for Terraform configurations. You can use [Tokens](https://docs.aws.amazon.com/cdk/latest/guide/tokens.html) to cast these attributes to the correct Terraform language syntax.

## Use Tokens

You may need to use Tokens for:

* [Module outputs](/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.

### Example

An EKS module requires a *list* of subnet ids in order to create a cluster. The VPC module outputs a list of subnets.

To pass the subnet id list to the EKS module, you can use `publicSubnetsOutput` to retrieve the list from the VPC. However, the `subnets` attribute
requires a list of strings. Use `Token.asList(vpc.publicSubnetsOutput)` to cast the interpolated module
output as a list of strings.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { TerraformStack, TerraformVariable, Token } from "cdktn";
  import { Construct } from "constructs";
  import { Vpc } from "./.gen/modules/terraform-aws-modules/aws/vpc";
  import { Eks } from "./.gen/modules/terraform-aws-modules/aws/eks";

  export class TokensStack extends TerraformStack {
    constructor(scope: Construct, id: string, vpcName: string) {
      super(scope, id);

      const logRetention = new TerraformVariable(this, "logRetentionInDays", {
        type: "number",
      });

      const vpc = new Vpc(this, vpcName, {
        name: vpcName,
        publicSubnets: ["10.0.1.0/24", "10.0.2.0/24"],
      });

      new Eks(this, "EksModule", {
        clusterName: "my-kubernetes-cluster",
        subnetIds: Token.asList(vpc.publicSubnetsOutput),
        cloudwatchLogGroupRetentionInDays: logRetention.numberValue,
      });
    }
  }
  ```

  ```java Java theme={null}
          TerraformVariable logRetention = new TerraformVariable(this, "logRetentionInDays", TerraformVariableConfig.builder()
                  .type("number")
                  .build()
          );

          Vpc vpc = new Vpc(this, "vpcName", VpcConfig.builder()
                  .name("vpcName")
                  .publicSubnets(Arrays.asList("10.0.1.0/24", "10.0.2.0/24"))
                  .build()
          );

          new Eks(this, "EksModules", EksConfig.builder()
                  .vpcId(vpc.getVpcIdOutput())
                  .clusterName("my-kubernetes-cluster")
                  .subnetIds(Token.asList(vpc.getPublicSubnetsOutput()))
                  .cloudwatchLogGroupRetentionInDays(logRetention.getNumberValue())
                  .build()
          );
  ```

  ```python Python theme={null}
          log_retention = TerraformVariable(self, "logRetentionInDays",
              type = "number"
          )

          vpc = Vpc(self, "vpcName",
              name = "vpcName",
              public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
          )

          Eks(self, "EksModules",
              vpc_id = vpc.vpc_id_output,
              cluster_name = "my-kubernetes-cluster",
              subnet_ids = Token.as_list(vpc.public_subnets_output),
              cloudwatch_log_group_retention_in_days = log_retention.number_value
          )
  ```

  ```csharp C# theme={null}
              // Add this to your project's .csproj file:
              // <ItemGroup>
              //     <ProjectReference Include=".gen\vpc\vpc.csproj" />
              // </ItemGroup>
              // <ItemGroup>
              //     <ProjectReference Include=".gen\eks\eks.csproj" />
              // </ItemGroup>
              TerraformVariable cloudwatchLogGroupRetentionInDays = new TerraformVariable(this, "cloudwatchLogGroupRetentionInDays", new TerraformVariableConfig
              {
                  Type = "number"
              });

              Vpc vpc = new Vpc(this, "vpc", new VpcConfig
              {
                  Name = "vpc",
                  PublicSubnets = new string[] { "10.0.1.0/24", "10.0.2.0/24" }
              });

              new Eks(this, "eks", new EksConfig
              {
                  ClusterName = "my-kubernetes-cluster",
                  SubnetIds = Token.AsList(vpc.PublicSubnetsOutput),
                  VpcId = vpc.VpcIdOutput,
                  CloudwatchLogGroupRetentionInDays = cloudwatchLogGroupRetentionInDays.NumberValue
              });
  ```

  ```go Go theme={null}
  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/terraform-aws-modules/aws/eks"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/terraform-aws-modules/aws/vpc"
  )

  func NewTokensStack(scope constructs.Construct, name string, vpcName string) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	logRetention := cdktn.NewTerraformVariable(stack, jsii.String("logRetentionInDays"), &cdktn.TerraformVariableConfig{
  		Type: jsii.String("number"),
  	})

  	vpc := vpc.NewVpc(stack, &vpcName, &vpc.VpcConfig{
  		Name:          &vpcName,
  		PublicSubnets: &[]*string{jsii.String("10.0.1.0/24"), jsii.String("10.0.2.0/24")},
  	})

  	eks.NewEks(stack, jsii.String("EksModule"), &eks.EksConfig{
  		ClusterName:                       jsii.String("my-kubernetes-cluster"),
  		SubnetIds:                         cdktn.Token_AsList(vpc.PublicSubnetsOutput(), nil),
  		CloudwatchLogGroupRetentionInDays: logRetention.NumberValue(),
  	})

  	return stack
  }

  ```
</CodeGroup>

Initially, CDKTN will resolve `Token.asList(vpc.publicSubnetsOutput)` to `["#{TOKEN[TOKEN.9]}"]` and `logRetention.numberValue` to a big negative number like `-123828381238238`.
Later in synthesis, CDKTN will resolve the token to `${module.<module id>.public_subnets}` and `${var.logRetentionInDays}`.

```json theme={null}
{
  "module": {
    "helloterraEksModule5DDB67AE": {
      "cluster_name": "my-kubernetes-cluster",
      "subnets": "${module.helloterraMyVpc62D94C17.public_subnets}"
    }
  }
}
```

Refer to the [AWS CDK documentation](https://docs.aws.amazon.com/cdk/latest/guide/tokens.html) for more detailed information about tokens.

### Using Terraform's `null` value

Some edge cases require passing the Terraform `null` value to for example an attribute of a resource.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { Token } from "cdktn";
  Token.nullValue();
  ```

  ```python Python theme={null}
  from cdktn import Token
  Token.null_value()
  ```

  ```java Java theme={null}
  import io.cdktn.cdktn.Token;
  Token.nullValue()
  ```

  ```csharp C# theme={null}
  using Io.Cdktn;
  Token.NullValue()
  ```

  ```go Go theme={null}
  import "github.com/open-constructs/cdk-terrain-go/cdktn"
  cdktn.Token_NullValue()
  ```
</CodeGroup>
