Rafay is a Kubernetes operations platform that provisions, secures, and manages the full cluster lifecycle across public cloud, private, and hybrid environments. It provides a single control plane for fleet-wide operations including automated provisioning, upgrades, and governance.
In this Learning Path, you’ll use Rafay to provision an Amazon EKS cluster with an AWS Graviton-based node group and deploy a workload to verify the setup.
You need the following accounts and tools before starting this Learning Path:
Confirm your AWS CLI is working by running the following command, which prints your account and user information:
aws sts get-caller-identity
Install the Kubernetes command-line tool by following the kubectl install guide .
Confirm the installation:
kubectl version --client
The output is similar to:
Client Version: v1.32.1
Kustomize Version: v5.5.0
RCTL is the Rafay CLI. You’ll use it to submit cluster manifests, check cluster status, download kubeconfig files, and delete clusters.
To download RCTL, log in to the Rafay console, navigate to My Tools > Download CLI, and download the binary for your operating system.
The downloads are .tar.bz2 files.
On macOS with Apple Silicon, extract the file with:
tar xvf rctl-darwin-arm64.tar.bz2
On Arm Linux, use the filename:
tar xvf rctl-linux-arm64.tar.bz2
RCTL is also available for x86_64 Linux and Windows. Modify the filename to match your platform as needed.
Move the binary to a directory in your search path:
sudo mv rctl /usr/local/bin/
Download the RCTL configuration file from the Rafay console. Navigate to My Tools > Download CLI Config and save the file.
The file name is formatted for your user information.
Copy the downloaded file to a known location and initialize rctl with it:
cp ~/Downloads/<filename>.json ~/rafay-config.json
rctl config init ~/rafay-config.json
The config command doesn’t have any output.
Verify the installation:
rctl version
The output is similar to:
VERSION: r4.2.0
BUILD: r4.2.0-1
BUILD-TIME: Thu 04 Jun 2026 07:17:05 AM UTC
ARCH: darwin/arm64
Confirm that rctl can reach the Rafay platform:
rctl config show
The output lists your account information, including the endpoints, keys, project, and organization information.
Rafay provisions EKS resources in your AWS account using a cross-account IAM role. You need two values from the Rafay console before running the script:
Save the following script as create-rafay-role.sh:
#!/bin/bash
set -euo pipefail
read -rp "Enter Rafay Account ID: " RAFAY_ACCOUNT_ID
read -rp "Enter External ID: " EXTERNAL_ID
ROLE_NAME="RafayEKSProvisioner"
REGION="us-east-1"
TRUST_POLICY=$(cat <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${RAFAY_ACCOUNT_ID}:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "${EXTERNAL_ID}"
}
}
}
]
}
EOF
)
echo "Creating IAM role: ${ROLE_NAME}"
aws iam create-role \
--role-name "${ROLE_NAME}" \
--assume-role-policy-document "${TRUST_POLICY}" \
--region "${REGION}"
INLINE_POLICY=$(cat <<'POLICY'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:CreateInstanceProfile",
"iam:CreateOpenIDConnectProvider",
"iam:DeleteOpenIDConnectProvider",
"iam:GetOpenIDConnectProvider",
"iam:ListOpenIDConnectProviderTags",
"iam:TagOpenIDConnectProvider",
"iam:DeleteInstanceProfile",
"iam:GetRole",
"iam:GetInstanceProfile",
"iam:RemoveRoleFromInstanceProfile",
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:ListInstanceProfiles",
"iam:AddRoleToInstanceProfile",
"iam:ListInstanceProfilesForRole",
"iam:PassRole",
"iam:DetachRolePolicy",
"iam:UpdateAssumeRolePolicy",
"iam:DeleteRolePolicy",
"iam:GetRolePolicy",
"iam:DeleteServiceLinkedRole",
"iam:CreateServiceLinkedRole",
"iam:TagRole",
"iam:ListRoleTags",
"iam:ListAttachedRolePolicies",
"iam:ListPolicyVersions",
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cloudformation:GetTemplate",
"cloudformation:ListStacks",
"cloudformation:ListStackResources",
"cloudformation:ListStackSets",
"cloudformation:ListChangeSets",
"cloudformation:DescribeStacks",
"cloudformation:DescribeStackResources",
"cloudformation:DescribeStackResource",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeChangeSet",
"cloudformation:DescribeStackSet",
"cloudformation:DeleteStack",
"cloudformation:DeleteChangeSet",
"cloudformation:DeleteStackSet",
"cloudformation:CreateStackSet",
"cloudformation:UpdateStackSet",
"cloudformation:CreateChangeSet",
"cloudformation:ExecuteChangeSet",
"cloudformation:CreateStack",
"cloudformation:UpdateStack"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"eks:AssociateEncryptionConfig",
"eks:CreatePodIdentityAssociation",
"eks:DescribePodIdentityAssociation",
"eks:DescribeClusterVersions",
"eks:DeletePodIdentityAssociation",
"eks:UpdatePodIdentityAssociation",
"eks:ListPodIdentityAssociations",
"eks:CreateAccessEntry",
"eks:CreateAddon",
"eks:CreateCluster",
"eks:CreateFargateProfile",
"eks:DescribeNodegroup",
"eks:DescribeCluster",
"eks:DescribeAddon",
"eks:DescribeAddonConfiguration",
"eks:DescribeAddonVersions",
"eks:DescribeFargateProfile",
"eks:DescribeUpdate",
"eks:ListUpdates",
"eks:UpdateClusterVersion",
"eks:UpdateClusterConfig",
"eks:ListAccessPolicies",
"eks:ListAccessEntries",
"eks:ListAssociatedAccessPolicies",
"eks:AssociateAccessPolicy",
"eks:ListClusters",
"eks:ListNodegroups",
"eks:ListAddons",
"eks:ListFargateProfiles",
"eks:ListTagsForResource",
"eks:CreateNodegroup",
"eks:TagResource",
"eks:AccessKubernetesApi",
"eks:DeleteCluster",
"eks:DeleteAccessEntry",
"eks:UntagResource",
"eks:UpdateAddon",
"eks:UpdateNodegroupConfig",
"eks:UpdateNodegroupVersion",
"eks:DeleteAddon",
"eks:DeleteFargateProfile",
"eks:DeleteNodegroup",
"eks:ListInsights",
"eks:DescribeInsight",
"eks:DescribeAccessEntry",
"eks:DisassociateAccessPolicy",
"eks:UpdateAccessEntry"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeScalingActivities",
"autoscaling:DescribeScheduledActions",
"autoscaling:CreateLaunchConfiguration",
"autoscaling:DeleteLaunchConfiguration",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:SetDesiredCapacity",
"autoscaling:UpdateAutoScalingGroup",
"autoscaling:DeleteAutoScalingGroup",
"autoscaling:CreateAutoScalingGroup",
"autoscaling:SuspendProcesses",
"autoscaling:CreateOrUpdateTags",
"autoscaling:DeleteTags"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "ec2:DeleteInternetGateway",
"Resource": "arn:aws:ec2:*:*:internet-gateway/*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:GetConsoleOutput",
"ec2:DeleteSubnet",
"ec2:DeleteTags",
"ec2:CreateNatGateway",
"ec2:CreateVpc",
"ec2:AttachInternetGateway",
"ec2:DescribeVpcAttribute",
"ec2:DeleteRouteTable",
"ec2:AssociateRouteTable",
"ec2:DescribeInternetGateways",
"ec2:CreateRoute",
"ec2:CreateInternetGateway",
"ec2:RevokeSecurityGroupEgress",
"ec2:CreateSecurityGroup",
"ec2:ModifyVpcAttribute",
"ec2:DeleteInternetGateway",
"ec2:DescribeRouteTables",
"ec2:ReleaseAddress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:DescribeTags",
"ec2:CreateTags",
"ec2:DeleteRoute",
"ec2:CreateRouteTable",
"ec2:DetachInternetGateway",
"ec2:DescribeNatGateways",
"ec2:DisassociateRouteTable",
"ec2:AllocateAddress",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSecurityGroupRules",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup",
"ec2:DeleteNatGateway",
"ec2:DeleteVpc",
"ec2:CreateSubnet",
"ec2:DescribeSubnets",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:describeAddresses",
"ec2:DescribeVpcs",
"ec2:CreateLaunchTemplate",
"ec2:CreateLaunchTemplateVersion",
"ec2:DescribeLaunchTemplates",
"ec2:RunInstances",
"ec2:DeleteLaunchTemplate",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeImageAttribute",
"ec2:DescribeKeyPairs",
"ec2:ImportKeyPair",
"ec2:DescribeInstances",
"ec2:ModifySubnetAttribute",
"ec2:ModifySecurityGroupRules",
"ec2:DescribeInstanceTypeOfferings",
"ec2:AssociateVpcCidrBlock",
"ec2:DescribeVolumes",
"ec2:CreateCarrierGateway",
"ec2:DeleteCarrierGateway",
"ec2:DescribeCarrierGateways",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "ssm:GetParameter",
"Resource": "arn:aws:ssm:*:*:parameter/*"
},
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:CreateGrant"
],
"Resource": "*"
},
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"logs:DeleteRetentionPolicy",
"logs:PutRetentionPolicy"
],
"Resource": "*"
}
]
}
POLICY
)
echo "Attaching inline policy to role"
aws iam put-role-policy \
--role-name "${ROLE_NAME}" \
--policy-name "RafayEKSProvisionerPolicy" \
--policy-document "${INLINE_POLICY}"
ROLE_ARN=$(aws iam get-role --role-name "${ROLE_NAME}" --query "Role.Arn" --output text)
echo ""
echo "Role ARN (copy this value into the Rafay console):"
echo "${ROLE_ARN}"
Make the script executable and run it:
chmod +x create-rafay-role.sh
./create-rafay-role.sh
You’ll be prompted for the Account ID and External ID. Enter these values from the previous step.
The output is similar to:
Enter Rafay Account ID: 123456789012
Enter External ID: abc123xyz
Creating IAM role: Proj-RafayEKSProvisioner
Attaching inline policy to role
Role ARN (copy this value into the Rafay console):
arn:aws:iam::111122223333:role/Proj-RafayEKSProvisioner
The Account ID, External ID, and Role ARN in this output are sample values.
Copy the Role ARN from the output.
With the Role ARN copied, complete the credential registration in the Rafay console:
Role ARN into the Role ARN field.aws-cloud-credential as the credential name.
Registered AWS cloud credential in the Rafay console
You’ve now installed kubectl and rctl, authenticated rctl to Rafay, and registered an AWS cloud credential.
Next, you’ll create the EKS cluster.