Create AWS FinSpace Kx Environments

The aws:finspace/kxEnvironment:KxEnvironment resource, part of the Pulumi AWS provider, provisions a FinSpace Kx environment: an isolated workspace for quantitative analytics with KMS encryption and optional network connectivity. This guide focuses on three capabilities: KMS encryption setup, Transit Gateway connectivity, and network ACL configuration.

Kx environments require KMS keys for encryption and may reference Transit Gateways for private network access. The examples are intentionally small. Combine them with your own KMS keys, Transit Gateways, and network infrastructure.

Create an environment with KMS encryption

Every Kx environment requires KMS encryption for data at rest, providing an isolated workspace for analytics workloads.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.kms.Key("example", {
    description: "Sample KMS Key",
    deletionWindowInDays: 7,
});
const exampleKxEnvironment = new aws.finspace.KxEnvironment("example", {
    name: "my-tf-kx-environment",
    kmsKeyId: example.arn,
});
import pulumi
import pulumi_aws as aws

example = aws.kms.Key("example",
    description="Sample KMS Key",
    deletion_window_in_days=7)
example_kx_environment = aws.finspace.KxEnvironment("example",
    name="my-tf-kx-environment",
    kms_key_id=example.arn)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/finspace"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("Sample KMS Key"),
			DeletionWindowInDays: pulumi.Int(7),
		})
		if err != nil {
			return err
		}
		_, err = finspace.NewKxEnvironment(ctx, "example", &finspace.KxEnvironmentArgs{
			Name:     pulumi.String("my-tf-kx-environment"),
			KmsKeyId: example.Arn,
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Kms.Key("example", new()
    {
        Description = "Sample KMS Key",
        DeletionWindowInDays = 7,
    });

    var exampleKxEnvironment = new Aws.FinSpace.KxEnvironment("example", new()
    {
        Name = "my-tf-kx-environment",
        KmsKeyId = example.Arn,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import com.pulumi.aws.finspace.KxEnvironment;
import com.pulumi.aws.finspace.KxEnvironmentArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Key("example", KeyArgs.builder()
            .description("Sample KMS Key")
            .deletionWindowInDays(7)
            .build());

        var exampleKxEnvironment = new KxEnvironment("exampleKxEnvironment", KxEnvironmentArgs.builder()
            .name("my-tf-kx-environment")
            .kmsKeyId(example.arn())
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: Sample KMS Key
      deletionWindowInDays: 7
  exampleKxEnvironment:
    type: aws:finspace:KxEnvironment
    name: example
    properties:
      name: my-tf-kx-environment
      kmsKeyId: ${example.arn}

The name property sets the environment identifier. The kmsKeyId property references a KMS key ARN that encrypts all data stored in the environment. Without additional configuration, the environment remains isolated from external networks.

Connect to internal networks via Transit Gateway

Analytics workloads often need to access data sources in corporate networks. Transit Gateway configuration bridges the environment to your VPCs.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.kms.Key("example", {
    description: "Sample KMS Key",
    deletionWindowInDays: 7,
});
const exampleTransitGateway = new aws.ec2transitgateway.TransitGateway("example", {description: "example"});
const exampleEnv = new aws.finspace.KxEnvironment("example_env", {
    name: "my-tf-kx-environment",
    description: "Environment description",
    kmsKeyId: example.arn,
    transitGatewayConfiguration: {
        transitGatewayId: exampleTransitGateway.id,
        routableCidrSpace: "100.64.0.0/26",
    },
    customDnsConfigurations: [{
        customDnsServerName: "example.finspace.amazonaws.com",
        customDnsServerIp: "10.0.0.76",
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.kms.Key("example",
    description="Sample KMS Key",
    deletion_window_in_days=7)
example_transit_gateway = aws.ec2transitgateway.TransitGateway("example", description="example")
example_env = aws.finspace.KxEnvironment("example_env",
    name="my-tf-kx-environment",
    description="Environment description",
    kms_key_id=example.arn,
    transit_gateway_configuration={
        "transit_gateway_id": example_transit_gateway.id,
        "routable_cidr_space": "100.64.0.0/26",
    },
    custom_dns_configurations=[{
        "custom_dns_server_name": "example.finspace.amazonaws.com",
        "custom_dns_server_ip": "10.0.0.76",
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2transitgateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/finspace"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("Sample KMS Key"),
			DeletionWindowInDays: pulumi.Int(7),
		})
		if err != nil {
			return err
		}
		exampleTransitGateway, err := ec2transitgateway.NewTransitGateway(ctx, "example", &ec2transitgateway.TransitGatewayArgs{
			Description: pulumi.String("example"),
		})
		if err != nil {
			return err
		}
		_, err = finspace.NewKxEnvironment(ctx, "example_env", &finspace.KxEnvironmentArgs{
			Name:        pulumi.String("my-tf-kx-environment"),
			Description: pulumi.String("Environment description"),
			KmsKeyId:    example.Arn,
			TransitGatewayConfiguration: &finspace.KxEnvironmentTransitGatewayConfigurationArgs{
				TransitGatewayId:  exampleTransitGateway.ID(),
				RoutableCidrSpace: pulumi.String("100.64.0.0/26"),
			},
			CustomDnsConfigurations: finspace.KxEnvironmentCustomDnsConfigurationArray{
				&finspace.KxEnvironmentCustomDnsConfigurationArgs{
					CustomDnsServerName: pulumi.String("example.finspace.amazonaws.com"),
					CustomDnsServerIp:   pulumi.String("10.0.0.76"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Kms.Key("example", new()
    {
        Description = "Sample KMS Key",
        DeletionWindowInDays = 7,
    });

    var exampleTransitGateway = new Aws.Ec2TransitGateway.TransitGateway("example", new()
    {
        Description = "example",
    });

    var exampleEnv = new Aws.FinSpace.KxEnvironment("example_env", new()
    {
        Name = "my-tf-kx-environment",
        Description = "Environment description",
        KmsKeyId = example.Arn,
        TransitGatewayConfiguration = new Aws.FinSpace.Inputs.KxEnvironmentTransitGatewayConfigurationArgs
        {
            TransitGatewayId = exampleTransitGateway.Id,
            RoutableCidrSpace = "100.64.0.0/26",
        },
        CustomDnsConfigurations = new[]
        {
            new Aws.FinSpace.Inputs.KxEnvironmentCustomDnsConfigurationArgs
            {
                CustomDnsServerName = "example.finspace.amazonaws.com",
                CustomDnsServerIp = "10.0.0.76",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import com.pulumi.aws.ec2transitgateway.TransitGateway;
import com.pulumi.aws.ec2transitgateway.TransitGatewayArgs;
import com.pulumi.aws.finspace.KxEnvironment;
import com.pulumi.aws.finspace.KxEnvironmentArgs;
import com.pulumi.aws.finspace.inputs.KxEnvironmentTransitGatewayConfigurationArgs;
import com.pulumi.aws.finspace.inputs.KxEnvironmentCustomDnsConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Key("example", KeyArgs.builder()
            .description("Sample KMS Key")
            .deletionWindowInDays(7)
            .build());

        var exampleTransitGateway = new TransitGateway("exampleTransitGateway", TransitGatewayArgs.builder()
            .description("example")
            .build());

        var exampleEnv = new KxEnvironment("exampleEnv", KxEnvironmentArgs.builder()
            .name("my-tf-kx-environment")
            .description("Environment description")
            .kmsKeyId(example.arn())
            .transitGatewayConfiguration(KxEnvironmentTransitGatewayConfigurationArgs.builder()
                .transitGatewayId(exampleTransitGateway.id())
                .routableCidrSpace("100.64.0.0/26")
                .build())
            .customDnsConfigurations(KxEnvironmentCustomDnsConfigurationArgs.builder()
                .customDnsServerName("example.finspace.amazonaws.com")
                .customDnsServerIp("10.0.0.76")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: Sample KMS Key
      deletionWindowInDays: 7
  exampleTransitGateway:
    type: aws:ec2transitgateway:TransitGateway
    name: example
    properties:
      description: example
  exampleEnv:
    type: aws:finspace:KxEnvironment
    name: example_env
    properties:
      name: my-tf-kx-environment
      description: Environment description
      kmsKeyId: ${example.arn}
      transitGatewayConfiguration:
        transitGatewayId: ${exampleTransitGateway.id}
        routableCidrSpace: 100.64.0.0/26
      customDnsConfigurations:
        - customDnsServerName: example.finspace.amazonaws.com
          customDnsServerIp: 10.0.0.76

The transitGatewayConfiguration property connects the environment to your network infrastructure. The transitGatewayId references an existing Transit Gateway, while routableCidrSpace defines the IP range for environment resources. The customDnsConfigurations property sets up Route 53 outbound resolvers, allowing the environment to resolve internal DNS names.

Control traffic with Transit Gateway network ACLs

When connecting to internal networks, you may need fine-grained control over traffic flows between the environment and corporate infrastructure.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.kms.Key("example", {
    description: "Sample KMS Key",
    deletionWindowInDays: 7,
});
const exampleTransitGateway = new aws.ec2transitgateway.TransitGateway("example", {description: "example"});
const exampleEnv = new aws.finspace.KxEnvironment("example_env", {
    name: "my-tf-kx-environment",
    description: "Environment description",
    kmsKeyId: example.arn,
    transitGatewayConfiguration: {
        transitGatewayId: exampleTransitGateway.id,
        routableCidrSpace: "100.64.0.0/26",
        attachmentNetworkAclConfigurations: [{
            ruleNumber: 1,
            protocol: "6",
            ruleAction: "allow",
            cidrBlock: "0.0.0.0/0",
            portRange: {
                from: 53,
                to: 53,
            },
            icmpTypeCode: {
                type: -1,
                code: -1,
            },
        }],
    },
    customDnsConfigurations: [{
        customDnsServerName: "example.finspace.amazonaws.com",
        customDnsServerIp: "10.0.0.76",
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.kms.Key("example",
    description="Sample KMS Key",
    deletion_window_in_days=7)
example_transit_gateway = aws.ec2transitgateway.TransitGateway("example", description="example")
example_env = aws.finspace.KxEnvironment("example_env",
    name="my-tf-kx-environment",
    description="Environment description",
    kms_key_id=example.arn,
    transit_gateway_configuration={
        "transit_gateway_id": example_transit_gateway.id,
        "routable_cidr_space": "100.64.0.0/26",
        "attachment_network_acl_configurations": [{
            "rule_number": 1,
            "protocol": "6",
            "rule_action": "allow",
            "cidr_block": "0.0.0.0/0",
            "port_range": {
                "from_": 53,
                "to": 53,
            },
            "icmp_type_code": {
                "type": -1,
                "code": -1,
            },
        }],
    },
    custom_dns_configurations=[{
        "custom_dns_server_name": "example.finspace.amazonaws.com",
        "custom_dns_server_ip": "10.0.0.76",
    }])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2transitgateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/finspace"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("Sample KMS Key"),
			DeletionWindowInDays: pulumi.Int(7),
		})
		if err != nil {
			return err
		}
		exampleTransitGateway, err := ec2transitgateway.NewTransitGateway(ctx, "example", &ec2transitgateway.TransitGatewayArgs{
			Description: pulumi.String("example"),
		})
		if err != nil {
			return err
		}
		_, err = finspace.NewKxEnvironment(ctx, "example_env", &finspace.KxEnvironmentArgs{
			Name:        pulumi.String("my-tf-kx-environment"),
			Description: pulumi.String("Environment description"),
			KmsKeyId:    example.Arn,
			TransitGatewayConfiguration: &finspace.KxEnvironmentTransitGatewayConfigurationArgs{
				TransitGatewayId:  exampleTransitGateway.ID(),
				RoutableCidrSpace: pulumi.String("100.64.0.0/26"),
				AttachmentNetworkAclConfigurations: finspace.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationArray{
					&finspace.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationArgs{
						RuleNumber: pulumi.Int(1),
						Protocol:   pulumi.String("6"),
						RuleAction: pulumi.String("allow"),
						CidrBlock:  pulumi.String("0.0.0.0/0"),
						PortRange: &finspace.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationPortRangeArgs{
							From: pulumi.Int(53),
							To:   pulumi.Int(53),
						},
						IcmpTypeCode: &finspace.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationIcmpTypeCodeArgs{
							Type: pulumi.Int(-1),
							Code: pulumi.Int(-1),
						},
					},
				},
			},
			CustomDnsConfigurations: finspace.KxEnvironmentCustomDnsConfigurationArray{
				&finspace.KxEnvironmentCustomDnsConfigurationArgs{
					CustomDnsServerName: pulumi.String("example.finspace.amazonaws.com"),
					CustomDnsServerIp:   pulumi.String("10.0.0.76"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Kms.Key("example", new()
    {
        Description = "Sample KMS Key",
        DeletionWindowInDays = 7,
    });

    var exampleTransitGateway = new Aws.Ec2TransitGateway.TransitGateway("example", new()
    {
        Description = "example",
    });

    var exampleEnv = new Aws.FinSpace.KxEnvironment("example_env", new()
    {
        Name = "my-tf-kx-environment",
        Description = "Environment description",
        KmsKeyId = example.Arn,
        TransitGatewayConfiguration = new Aws.FinSpace.Inputs.KxEnvironmentTransitGatewayConfigurationArgs
        {
            TransitGatewayId = exampleTransitGateway.Id,
            RoutableCidrSpace = "100.64.0.0/26",
            AttachmentNetworkAclConfigurations = new[]
            {
                new Aws.FinSpace.Inputs.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationArgs
                {
                    RuleNumber = 1,
                    Protocol = "6",
                    RuleAction = "allow",
                    CidrBlock = "0.0.0.0/0",
                    PortRange = new Aws.FinSpace.Inputs.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationPortRangeArgs
                    {
                        From = 53,
                        To = 53,
                    },
                    IcmpTypeCode = new Aws.FinSpace.Inputs.KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationIcmpTypeCodeArgs
                    {
                        Type = -1,
                        Code = -1,
                    },
                },
            },
        },
        CustomDnsConfigurations = new[]
        {
            new Aws.FinSpace.Inputs.KxEnvironmentCustomDnsConfigurationArgs
            {
                CustomDnsServerName = "example.finspace.amazonaws.com",
                CustomDnsServerIp = "10.0.0.76",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import com.pulumi.aws.ec2transitgateway.TransitGateway;
import com.pulumi.aws.ec2transitgateway.TransitGatewayArgs;
import com.pulumi.aws.finspace.KxEnvironment;
import com.pulumi.aws.finspace.KxEnvironmentArgs;
import com.pulumi.aws.finspace.inputs.KxEnvironmentTransitGatewayConfigurationArgs;
import com.pulumi.aws.finspace.inputs.KxEnvironmentCustomDnsConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Key("example", KeyArgs.builder()
            .description("Sample KMS Key")
            .deletionWindowInDays(7)
            .build());

        var exampleTransitGateway = new TransitGateway("exampleTransitGateway", TransitGatewayArgs.builder()
            .description("example")
            .build());

        var exampleEnv = new KxEnvironment("exampleEnv", KxEnvironmentArgs.builder()
            .name("my-tf-kx-environment")
            .description("Environment description")
            .kmsKeyId(example.arn())
            .transitGatewayConfiguration(KxEnvironmentTransitGatewayConfigurationArgs.builder()
                .transitGatewayId(exampleTransitGateway.id())
                .routableCidrSpace("100.64.0.0/26")
                .attachmentNetworkAclConfigurations(KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationArgs.builder()
                    .ruleNumber(1)
                    .protocol("6")
                    .ruleAction("allow")
                    .cidrBlock("0.0.0.0/0")
                    .portRange(KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationPortRangeArgs.builder()
                        .from(53)
                        .to(53)
                        .build())
                    .icmpTypeCode(KxEnvironmentTransitGatewayConfigurationAttachmentNetworkAclConfigurationIcmpTypeCodeArgs.builder()
                        .type(-1)
                        .code(-1)
                        .build())
                    .build())
                .build())
            .customDnsConfigurations(KxEnvironmentCustomDnsConfigurationArgs.builder()
                .customDnsServerName("example.finspace.amazonaws.com")
                .customDnsServerIp("10.0.0.76")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:kms:Key
    properties:
      description: Sample KMS Key
      deletionWindowInDays: 7
  exampleTransitGateway:
    type: aws:ec2transitgateway:TransitGateway
    name: example
    properties:
      description: example
  exampleEnv:
    type: aws:finspace:KxEnvironment
    name: example_env
    properties:
      name: my-tf-kx-environment
      description: Environment description
      kmsKeyId: ${example.arn}
      transitGatewayConfiguration:
        transitGatewayId: ${exampleTransitGateway.id}
        routableCidrSpace: 100.64.0.0/26
        attachmentNetworkAclConfigurations:
          - ruleNumber: 1
            protocol: '6'
            ruleAction: allow
            cidrBlock: 0.0.0.0/0
            portRange:
              from: 53
              to: 53
            icmpTypeCode:
              type: -1
              code: -1
      customDnsConfigurations:
        - customDnsServerName: example.finspace.amazonaws.com
          customDnsServerIp: 10.0.0.76

The attachmentNetworkAclConfigurations property defines network ACL rules for the Transit Gateway attachment. Each rule specifies a ruleNumber for ordering, protocol (6 for TCP), ruleAction (allow or deny), and cidrBlock for source/destination matching. The portRange property controls which ports are accessible; here, port 53 allows DNS traffic.

Beyond these examples

These snippets focus on specific Kx environment features: KMS encryption configuration, Transit Gateway connectivity, and network ACL rules for traffic control. They’re intentionally minimal rather than full analytics platform deployments.

The examples reference pre-existing infrastructure such as KMS keys for encryption and Transit Gateways for network connectivity. They focus on configuring the environment rather than provisioning the surrounding infrastructure.

To keep things focused, common environment patterns are omitted, including:

  • Tagging for cost allocation and organization
  • Environment descriptions and metadata
  • Cluster and database provisioning within the environment
  • IAM permissions for environment access

These omissions are intentional: the goal is to illustrate how each environment feature is wired, not provide drop-in analytics platform modules. See the FinSpace Kx Environment resource reference for all available configuration options.

Let's create AWS FinSpace Kx Environments

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
What are the required fields to create a KX environment?
You must provide kmsKeyId (KMS key ID for encryption), name (environment name), and region (which defaults to your provider’s configured region).
What region does my environment get created in?
The environment is created in the region specified by the region property, which defaults to the region configured in your provider.
Networking & Connectivity
How do I connect my KX environment to an internal network?
Configure transitGatewayConfiguration with transitGatewayId and routableCidrSpace. You can also add attachmentNetworkAclConfigurations for network ACL rules.
How do I configure custom DNS servers for my environment?
Use customDnsConfigurations with customDnsServerName and customDnsServerIp to set up Route-53 outbound resolvers.
How do I configure network ACLs for transit gateway attachments?
Within transitGatewayConfiguration, add attachmentNetworkAclConfigurations with ruleNumber, protocol, ruleAction, cidrBlock, and optional portRange or icmpTypeCode.
Resource Properties
What's the availabilityZones property used for?
The availabilityZones output property lists AWS Availability Zone IDs where the environment is available, which is important when selecting VPC subnets for cluster creation.
What format are the timestamp properties in?
Timestamps like createdTimestamp and lastModifiedTimestamp use epoch time in seconds. For example, November 1, 2021 12:00:00 PM UTC is represented as 1635768000.

Using a different cloud?

Explore analytics guides for other cloud providers: