Skip to main content
Skip table of contents

Installing with Terraform Modules (Kubernetes)

The terraform-exostellar-modules are one of the newest Exostellar installation approaches designed to simplify the setup process.

Prerequisites

Before running the Terraform commands on terraform-exostellar-modules, ensure that your environment meets the following requirements:

  • Terraform: Version 1.8+

  • Helm: Version 3.14.2+

  • AWS CLI

  • AWS Authentication, Credentials, and Region
    Please properly configure AWS authentication and default region in your local environment.

AWS Authentication and Credentials Setup Methods

You can set up credentials using various methods such as command-line options, environment variables, assume role, credentials files, configuration files, etc.

  • Command-line Options

    BASH
    aws configure sso
    BASH
    aws s3 ls --profile profile1
  • Environment Variables

    BASH
    export AWS_ACCESS_KEY_ID=<AccessKeyId>
    export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
    export AWS_SESSION_TOKEN=<SessionToken>
  • Assume role

    CODE
    aws sts assume-role \
        --role-arn arn:aws:iam::123456789012:role/xaccounts3access \
        --role-session-name s3-access-example
  • Credentials and Configuration File:
    Update in ~/.aws/credentials and ~/.aws/config

    BASH
    aws configure

Please ensure the default region is set for deployment. If not set above, use the following command:

BASH
aws configure set default.region us-east-2

Ensure the account has the following IAM permissions:

IAM Permissions for the AWS Account - Standalone Flow

When working with the standalone flow, i.e., deploying everything from scratch using the examples/standalone-flow module, use the following IAM policy.

Please add your AWS account ID and cluster name to the policy below.

JSON
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iam:PassRole"
			],
			"Resource": [
				"arn:aws:iam::<account-id>:role/<cluster-name>*",
				"arn:aws:iam::<account-id>:role/terraform-*"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"autoscaling:CompleteLifecycleAction",
				"autoscaling:CreateAutoScalingGroup",
				"autoscaling:DeleteAutoScalingGroup",
				"autoscaling:EnableMetricsCollection",
				"autoscaling:PutNotificationConfiguration",
				"autoscaling:UpdateAutoScalingGroup"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"ec2:AllocateAddress",
				"ec2:AssignPrivateIpAddresses",
				"ec2:AssociateRouteTable",
				"ec2:AttachInternetGateway",
				"ec2:AttachNetworkInterface",
				"ec2:AuthorizeSecurityGroupEgress",
				"ec2:AuthorizeSecurityGroupIngress",
				"ec2:CreateFleet",
				"ec2:CreateInternetGateway",
				"ec2:CreateLaunchTemplate",
				"ec2:CreateLaunchTemplateVersion",
				"ec2:CreateNatGateway",
				"ec2:CreateNetworkAclEntry",
				"ec2:CreateNetworkInterface",
				"ec2:CreateNetworkInterfacePermission",
				"ec2:CreateRoute",
				"ec2:CreateRouteTable",
				"ec2:CreateSecurityGroup",
				"ec2:CreateSubnet",
				"ec2:CreateTags",
				"ec2:CreateVpc",
				"ec2:DeleteInternetGateway",
				"ec2:DeleteLaunchTemplate",
				"ec2:DeleteNatGateway",
				"ec2:DeleteNetworkAclEntry",
				"ec2:DeleteNetworkInterface",
				"ec2:DeleteRoute",
				"ec2:DeleteRouteTable",
				"ec2:DeleteSecurityGroup",
				"ec2:DeleteSubnet",
				"ec2:DeleteTags",
				"ec2:DeleteVpc",
				"ec2:DescribeAddresses",
				"ec2:DescribeAddressesAttribute",
				"ec2:DescribeAvailabilityZones",
				"ec2:DescribeDhcpOptions",
				"ec2:DescribeImages",
				"ec2:DescribeInstanceAttribute",
				"ec2:DescribeInstances",
				"ec2:DescribeInstanceTypes",
				"ec2:DescribeInternetGateways",
				"ec2:DescribeKeyPairs",
				"ec2:DescribeLaunchTemplates",
				"ec2:DescribeLaunchTemplateVersions",
				"ec2:DescribeNatGateways",
				"ec2:DescribeNetworkAcls",
				"ec2:DescribeNetworkInterfaces",
				"ec2:DescribeRouteTables",
				"ec2:DescribeSecurityGroupRules",
				"ec2:DescribeSecurityGroups",
				"ec2:DescribeSnapshots",
				"ec2:DescribeSubnets",
				"ec2:DescribeTags",
				"ec2:DescribeVolumes",
				"ec2:DescribeVpcAttribute",
				"ec2:DescribeVpcs",
				"ec2:DetachInternetGateway",
				"ec2:DetachNetworkInterface",
				"ec2:DisassociateAddress",
				"ec2:DisassociateRouteTable",
				"ec2:ModifyInstanceAttribute",
				"ec2:ModifyLaunchTemplate",
				"ec2:ModifyNetworkInterfaceAttribute",
				"ec2:ModifySubnetAttribute",
				"ec2:ModifyVpcAttribute",
				"ec2:ReleaseAddress",
				"ec2:RevokeSecurityGroupEgress",
				"ec2:RevokeSecurityGroupIngress",
				"ec2:RunInstances",
				"ec2:TerminateInstances"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"eks:AssociateAccessPolicy",
				"eks:CreateAccessEntry",
				"eks:CreateAddon",
				"eks:CreateCluster",
				"eks:CreateNodegroup",
				"eks:DeleteAccessEntry",
				"eks:DeleteAddon",
				"eks:DeleteCluster",
				"eks:DeleteNodegroup",
				"eks:DescribeAccessEntry",
				"eks:DescribeAddon",
				"eks:DescribeAddonVersions",
				"eks:DescribeCluster",
				"eks:DescribeNodegroup",
				"eks:DisassociateAccessPolicy",
				"eks:ListAssociatedAccessPolicies",
				"eks:ListNodegroups",
				"eks:TagResource"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"events:PutRule",
				"events:PutTargets"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"iam:AddRoleToInstanceProfile",
				"iam:AttachRolePolicy",
				"iam:CreateInstanceProfile",
				"iam:CreateOpenIDConnectProvider",
				"iam:CreatePolicy",
				"iam:CreateRole",
				"iam:DeleteInstanceProfile",
				"iam:DeleteOpenIDConnectProvider",
				"iam:DeletePolicy",
				"iam:DeleteRole",
				"iam:DeleteRolePolicy",
				"iam:DetachRolePolicy",
				"iam:GetInstanceProfile",
				"iam:GetOpenIDConnectProvider",
				"iam:GetPolicy",
				"iam:GetPolicyVersion",
				"iam:GetRole",
				"iam:GetRolePolicy",
				"iam:ListAttachedRolePolicies",
				"iam:ListInstanceProfilesForRole",
				"iam:ListPolicyVersions",
				"iam:ListRolePolicies",
				"iam:PutRolePolicy",
				"iam:RemoveRoleFromInstanceProfile",
				"iam:TagInstanceProfile",
				"iam:TagOpenIDConnectProvider",
				"iam:TagPolicy",
				"iam:TagRole"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"kms:CreateAlias",
				"kms:CreateGrant",
				"kms:CreateKey",
				"kms:DeleteAlias",
				"kms:DescribeKey",
				"kms:EnableKeyRotation",
				"kms:GetKeyPolicy",
				"kms:GetKeyRotationStatus",
				"kms:ListAliases",
				"kms:ListResourceTags",
				"kms:PutKeyPolicy",
				"kms:RetireGrant",
				"kms:ScheduleKeyDeletion",
				"kms:TagResource"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"logs:CreateLogGroup",
				"logs:CreateLogStream",
				"logs:DeleteLogGroup",
				"logs:DescribeLogGroups",
				"logs:ListTagsForResource",
				"logs:PutRetentionPolicy",
				"logs:TagResource"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"aws-marketplace:ListEntities"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"s3:GetObject",
				"s3:ListBucket"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"ssm:RegisterManagedInstance",
				"ssm:UpdateInstanceInformation"
			],
			"Resource": "*"
		}
	]
}
IAM Permissions for the AWS Account - Using an Existing Cluster

When working with existing EKS clusters, use the following IAM policy.

When working with the existing cluster flow, i.e., deploying the Exostellar setup using the examples/existing-cluster-flow module on top of an existing cluster, use the following IAM policy.

Please add your AWS account ID and cluster name to the policy below.

JSON
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"iam:PassRole"
			],
			"Resource": [
				"arn:aws:iam::<account-id>:role/<cluster-name>*",
				"arn:aws:iam::<account-id>:role/terraform-*"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"aws-marketplace:ListEntities"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"ec2:AuthorizeSecurityGroupEgress",
				"ec2:AuthorizeSecurityGroupIngress",
				"ec2:CreateSecurityGroup",
				"ec2:CreateTags",
				"ec2:DeleteSecurityGroup",
				"ec2:DescribeDhcpOptions",
				"ec2:DescribeImages",
				"ec2:DescribeInstanceAttribute",
				"ec2:DescribeInstances",
				"ec2:DescribeInstanceTypes",
				"ec2:DescribeInternetGateways",
				"ec2:DescribeNatGateways",
				"ec2:DescribeNetworkInterfaces",
				"ec2:DescribeRouteTables",
				"ec2:DescribeSecurityGroups",
				"ec2:DescribeSnapshots",
				"ec2:DescribeSubnets",
				"ec2:DescribeTags",
				"ec2:DescribeVolumes",
				"ec2:DescribeVpcAttribute",
				"ec2:DescribeVpcs",
				"ec2:ModifyInstanceAttribute",
				"ec2:RevokeSecurityGroupEgress",
				"ec2:RunInstances",
				"ec2:TerminateInstances"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"eks:DescribeCluster",
				"eks:DescribeNodegroup",
				"eks:ListNodegroups"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"iam:AddRoleToInstanceProfile",
				"iam:AttachRolePolicy",
				"iam:CreateInstanceProfile",
				"iam:CreateRole",
				"iam:DeleteInstanceProfile",
				"iam:DeleteRole",
				"iam:DeleteRolePolicy",
				"iam:DetachRolePolicy",
				"iam:GetInstanceProfile",
				"iam:GetPolicy",
				"iam:GetPolicyVersion",
				"iam:GetRole",
				"iam:GetRolePolicy",
				"iam:ListAttachedRolePolicies",
				"iam:ListInstanceProfilesForRole",
				"iam:ListRolePolicies",
				"iam:PutRolePolicy",
				"iam:RemoveRoleFromInstanceProfile",
				"iam:TagInstanceProfile",
				"iam:TagRole"
			],
			"Resource": "*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"s3:GetObject",
				"s3:ListBucket"
			],
			"Resource": "*"
		}
	]
}
SSH Key Creation

Use the following command to create a new SSH key pair:

BASH
aws ec2 create-key-pair --key-name 'my-dev-key' --query 'KeyMaterial' --output text --region us-east-2 > my-dev-key.pem

Modify the permission to secure the key:

BASH
chmod 400 my-dev-key.pem
  • terraform-exostellar-modules: v0.0.1+
    terraform-exostellar-modules-0.0.1.tar.gz
    Download, extract, and open a terminal from inside the extracted directory to proceed with the next steps in this doc. You should see the following examples, modules, scripts, and the README.

    CODE
    ├── examples/
    │   ├── existing-cluster-flow/
    │   └── standalone-flow/
    ├── modules/
    │   ├── ems/
    │   ├── existing-cluster-full/
    │   ├── iam/
    │   ├── infra/
    │   ├── karpenter/
    │   └── standalone-full/
    ├── scripts/
    └── README.md

Installation Steps

Creating a Sandbox EKS Cluster and Deploying the Management Server

If you'd like to deploy a full Exostellar setup from scratch—including:

  • A new EKS cluster

  • Controllers and Workers IAMs

  • Exostellar Management Server (EMS)

  • Exostellar’s Karpenter (exokarpenter)

Use the example module located at:examples/standalone-flow/

Step 1: Configure the Terraform Module

Open examples/standalone-flow/main.tf and update the necessary values:

Variable

Description

Infrastructure-related resources

eks_cluster

Name of the EKS Cluster to be created.

aws_region

AWS region where the cluster is deployed. Default: us-east-1.

eks_version

EKS (Kubernetes) version. Default: 1.31.

vpc_cidr

CIDR block for VPC to be created for EKS Cluster.

Exostellar Management Server (EMS) configurations

ssh_key_name

Name of an existing SSH key pair in AWS (only the key-pair resource name, not the local file name).

ems_ami_id

AMI ID for Exostellar Management Server. Must match the selected aws_region.

ems_instance_type

EC2 instance type for EMS. Default: m5d.xlarge.

ems_volume_size_gb

EMS volume size in GB. Default: 100.

ems_termination_protection

Whether to enable termination protection on the EMS instance. Default: true.

profile_availability_zone

Profile's availability zone. Must match the selected aws_region.

Controller and Worker configurations

xspot_enable_hyperthreading

Enable hyperthreading. Default: true.

xspot_enable_balloon

Enable self-ballooning. Default: true.

Exostellar Karpenter configurations

xkarpenter_version

xKarpenter's version. Default is v2.0.1.

Step 2: Deploy with Terraform

Run the Terraform commands to deploy the standalone-flow’s stack:

CODE
terraform -chdir=./examples/standalone-flow init
terraform -chdir=./examples/standalone-flow plan -input=false
terraform -chdir=./examples/standalone-flow apply -auto-approve

Note: Terraform commands are idempotent. You can re-run them safely to retry failed operations or refresh the state.

Exostellar Management Server Console Access

  • URL: https://<ems_public_ip>

  • Username: exostellar_management_server_console_admin_username

  • Password: exostellar_management_server_console_admin_password

Exostellar Management Server SSH Access

CODE
ssh -i <ssh-private-key> rocky@<ems_public_ip>
  • The rocky is the username for the RockyLinux VM, on which EMS is built.

  • SSH private key is the private key corresponding to ssh_key_name specified as input without file extension.

Deploying the Management Server into an Existing EKS Cluster

If you already have an Amazon EKS cluster running and want to deploy the Exostellar setup on top of it—including the following components:

  • Controller and Worker IAM roles

  • Exostellar Management Server (EMS)

  • Exostellar’s Karpenter (exokarpenter)

Use the example module provided at examples/existing-cluster-flow

Step 1: Configure main.tf for Your Environment

Edit the following variables in examples/existing-cluster-flow/main.tf according to your setup:

Variable

Description

Infrastructure-related resources

eks_cluster

Name of your existing EKS cluster.

aws_region

AWS region where the cluster is deployed. Default: us-east-1.

eks_version

Kubernetes version of your EKS cluster. Default: 1.31.

vpc_id

VPC ID associated with the EKS cluster.

Exostellar Management Server (EMS) configurations

ssh_key_name

Name of an existing SSH key pair in AWS (only the key-pair resource name, not the local file name).

public_subnet_id

Public subnet ID from the same VPC (identified via vpc_id). This is used to expose EMS to the internet.
Note: Must be in the same Availability Zone as private_subnet_id and profile_availability_zone.

profile_availability_zone

Exostellar profile's availability zone. Default is us-east-1a.

ems_ami_id

AMI ID for Exostellar Management Server. Must match the selected aws_region.

ems_instance_type

EC2 instance type for EMS. Default: m5d.xlarge.

ems_volume_size_gb

EMS volume size in GB. Default: 100.

ems_termination_protection

Whether to enable termination protection on the EMS instance. Default: true.

ems_security_group_ids

A list of security group IDs. Must include:

  • The EKS cluster security group (not the default one)

  • The node security group

Include others as needed.

Controller and Worker configurations

xspot_enable_hyperthreading

Enable hyperthreading. Default: true.

xspot_enable_balloon

Enable self-ballooning. Default: true.

private_subnet_id

The ID of the private subnet from the VPC (specified using vpc_id) associated with the existing EKS cluster. EMS will use this subnet to communicate internally with Controllers and Workers.
Note: Must be in the same AZ as specified in profile_availability_zone.

Exostellar Karpenter configurations

xkarpenter_version

xKarpenter's version. Default is v2.0.1.

Step 2: Deploy Using Terraform

Run the Terraform commands to deploy the existing-cluster-flow’s stack:

BASH
terraform -chdir=./examples/existing-cluster-flow init
terraform -chdir=./examples/existing-cluster-flow plan -input=false
terraform -chdir=./examples/existing-cluster-flow apply -auto-approve

Note: Terraform commands are idempotent. You can re-run them safely to retry failed operations or refresh the state.

Output on Successful Deployment

You will see output similar to the following:

BASH
eks_cluster = "xio-standalone"
environment = "k8s"
exostellar_management_server_console_admin_password = "xxxxxxxx"
exostellar_management_server_console_admin_username = "admin@xxxx"
exostellar_management_server_private_ip = "10.0.141.xx"
exostellar_management_server_public_ip = "52.53.171.x"
xkarpenter_namespace = "exokarpenter"
xkarpenter_version = "v2.0.1"
xspot_controller_instance_profile_arn = "arn:aws:iam::97709900xxxx:instance-profile/xio-standalone-xspot-controller"
xspot_controller_role_arn = "arn:aws:iam::97709900xxxx:role/xio-standalone-xspot-controller"
xspot_worker_instance_profile_arn = "arn:aws:iam::97709900xxxx:instance-profile/xio-standalone-xspot-worker"
xspot_worker_role_arn = "arn:aws:iam::97709900xxxx:role/xio-standalone-xspot-worker"

Exostellar Management Server Console Access

  • URL: https://<ems_public_ip>

  • Username: exostellar_management_server_console_admin_username

  • Password: exostellar_management_server_console_admin_password

Exostellar Management Server SSH Access

CODE
ssh -i <ssh-private-key> rocky@<ems_public_ip>
  • The rocky is the username for the RockyLinux VM, on which EMS is built.

  • SSH private key is the private key corresponding to ssh_key_name specified as input without file extension.

Cleaning Up

Standalone Flow

To remove all resources created by the standalone-flow module—including the EKS cluster, Controller and Worker IAM roles, EMS, and exokarpenter — run:

BASH
terraform -chdir=./examples/standalone-flow destroy -auto-approve -refresh=true

This will completely tear down the deployed infrastructure.

Existing Cluster Flow

To clean up everything deployed except the EKS cluster (which was pre-existing), run the following:

BASH
terraform -chdir=./examples/existing-cluster-flow destroy -auto-approve -refresh=true

This will delete the Controller and Worker IAM roles, EMS instance, and exokarpenter components—while preserving your original EKS cluster.

Additional Help and Support

For more configuration options, variables, and usage examples, refer to the relevant README.md files located throughout the repository:

BASH
├── examples/
│   ├── existing-cluster-flow/
│   │   └── README.md
│   └── standalone-flow/
│       └── README.md
├── modules/
│   ├── ems/
│   │   └── README.md
│   ├── existing-cluster-full/
│   │   └── README.md
│   ├── iam/
│   │   └── README.md
│   ├── infra/
│   │   └── README.md
│   ├── karpenter/
│   │   └── README.md
│   └── standalone-full/
│       └── README.md
└── README.md

If you run into any issues:

  1. Capture as much terminal output as possible.

  2. Compress the entire repository directory (including hidden files) using .zip or .tar.

  3. Submit the archive along with a description of your issue to Exostellar Customer Support.

Our team will assist you in troubleshooting and resolving the issue promptly.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.