docs-mintlify/admin/deployment/dedicated/aws/byoc.mdx
With Bring Your Own Cloud (BYOC) on AWS, all the components interacting with private data are deployed on the customer infrastructure on AWS and managed by the Cube Control Plane via the Cube Operator. This document provides step-by-step instructions for deploying Cube BYOC on AWS.
<Note>Available on the Enterprise plan. Contact us for details. For private API access from your applications and BI tools, see Private API Connectivity.
</Note>The bulk of provisioning work will be done remotely by Cube automation. However, to get started, you'll need to provide Cube with the necessary access along with some additional information that includes:
In addition to that, you'll need to make sure you have sufficient access to create
the CubeCloudBYOC IAM role that would allow Cube to:
Restrictive SCPs may block RDS provisioning. Amazon RDS needs a service-linked
role named AWSServiceRoleForRDS in the account. The policy below grants
iam:CreateServiceLinkedRole for rds.amazonaws.com, so Cube creates it during
provisioning — but if your organization's SCPs deny IAM writes, the grant is
present in the policy without being effective in the account, and provisioning
fails with a message that names a parameter rather than a permission:
InvalidParameterValue: Unable to create the resource.
Verify that you have permission to create service linked role.
To rule this out, run the following once in the target account before granting
Cube access. InvalidInput: ... has been taken in this account means the role
already exists and no action is needed.
aws iam create-service-linked-role --aws-service-name rds.amazonaws.com
If the command itself is denied by an SCP, the same denial will block Cube during
provisioning — ask your AWS organization administrator to permit
iam:CreateServiceLinkedRole for rds.amazonaws.com in this account.
Navigate to IAM->Policies and create a new policy called CubeCloudBYOC
with the following JSON content. Please substitute AWS_ACCOUNT_ID with your
actual account ID.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
"ec2:DescribeAddresses",
"ec2:DescribeAddressesAttribute",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInternetGateways",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribePrefixLists",
"ec2:DescribeRegions",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcClassicLink",
"ec2:DescribeVpcClassicLinkDnsSupport",
"ec2:DescribeVpcEndpointServiceConfigurations",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeVpcPeeringConnections",
"ec2:DescribeVpcs",
"ec2:DescribeVolumes",
"ec2:RunInstances",
"eks:DescribeCluster",
"eks:DescribeNodegroup",
"eks:ListClusters",
"iam:GetRole",
"sts:DecodeAuthorizationMessage",
"rds:DescribeDBInstances",
"rds:DescribeDBSubnetGroups",
"rds:DescribeDBParameterGroups",
"rds:ListTagsForResource"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": ["arn:aws:s3:::cube-store-*"]
},
{
"Effect": "Allow",
"Action": [
"ec2:AllocateAddress",
"ec2:CreateInternetGateway",
"ec2:CreateLaunchTemplate",
"ec2:CreateNatGateway",
"ec2:CreateRoute",
"ec2:CreateRouteTable",
"ec2:CreateSecurityGroup",
"ec2:CreateSubnet",
"ec2:CreateTags",
"ec2:CreateVpc",
"ec2:CreateVpcEndpoint",
"ec2:CreateVpcEndpointServiceConfiguration",
"ec2:CreateVpcPeeringConnection",
"ec2:CreateVolume",
"eks:CreateCluster",
"eks:CreateNodegroup",
"iam:CreateOpenIDConnectProvider",
"iam:PassRole",
"iam:TagOpenIDConnectProvider",
"logs:CreateLogDelivery",
"kms:TagResource",
"kms:CreateKey",
"rds:CreateDBInstance",
"rds:CreateDBSubnetGroup",
"rds:AddTagsToResource"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestTag/Created-By": "CubeCloud"
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:AddRoleToInstanceProfile",
"iam:AttachRolePolicy",
"iam:CreateInstanceProfile",
"iam:CreateOpenIDConnectProvider",
"iam:CreatePolicy",
"iam:CreatePolicyVersion",
"iam:CreateRole",
"iam:CreateServiceLinkedRole",
"iam:DeleteInstanceProfile",
"iam:DeleteOpenIDConnectProvider",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DeleteServiceLinkedRole",
"iam:DetachRolePolicy",
"iam:GetInstanceProfile",
"iam:GetOpenIDConnectProvider",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListAttachedRolePolicies",
"iam:ListInstanceProfilesForRole",
"iam:ListOpenIDConnectProviderTags",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:RemoveRoleFromInstanceProfile",
"iam:TagInstanceProfile",
"iam:TagOpenIDConnectProvider",
"iam:TagPolicy",
"iam:TagRole",
"iam:UpdateOpenIDConnectProviderThumbprint"
],
"Resource": [
"arn:aws:iam::{AWS_ACCOUNT_ID}:instance-profile/CubeCloud*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:instance-profile/cubeapp-*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:instance-profile/cube-store-*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:oidc-provider/oidc.eks.*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:policy/CubeCloud*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:policy/cubeapp-*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:role/CubeCloud*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:role/cubeapp-*",
"arn:aws:iam::{AWS_ACCOUNT_ID}:role/cube-store-*"
],
"Condition": {
"StringEquals": {
"iam:ResourceTag/Created-By": "CubeCloud"
}
}
},
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:AWSServiceName": [
"eks.amazonaws.com",
"eks-nodegroup.amazonaws.com",
"eks-fargate.amazonaws.com",
"rds.amazonaws.com"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup"
],
"Resource": ["*"],
"Condition": {
"StringEquals": {
"autoscaling:ResourceTag/Created-By": "CubeCloud"
}
}
},
{
"Effect": "Allow",
"Action": ["eks:*", "kms:*"],
"Resource": ["*"],
"Condition": {
"StringEquals": {
"aws:ResourceTag/Created-By": "CubeCloud"
}
}
},
{
"Effect": "Allow",
"Action": ["ec2:*"],
"Resource": ["*"],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Created-By": "CubeCloud"
}
}
},
{
"Effect": "Allow",
"Action": [
"rds:ModifyDBInstance",
"rds:DeleteDBInstance",
"rds:DeleteDBSubnetGroup",
"rds:RebootDBInstance",
"rds:StartDBInstance",
"rds:StopDBInstance",
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource"
],
"Resource": ["*"],
"Condition": {
"StringEquals": {
"aws:ResourceTag/Created-By": "CubeCloud"
}
}
}
]
}
Navigate to IAM->Roles and create a new Role called CubeCloudBYOC. Select
AWS Account as the Trusted entity. Type and enter
arn:aws:iam::307491255751:root, which is the Cube BYOC provisioner
account. On the Add permissions page, find and select the CubeCloudBYOC
policy you created earlier. On the final Review and create page, edit the
Trust Policy to make it look like this.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::307491255751:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "cube-cloud-byoc"
}
}
}
]
}
Make sure to include "sts:ExternalId": "cube-cloud-byoc" in the Condition section.
The actual deployment will be done by Cube automation. All that's left to do is notify your Cube contact point that access has been granted, and pass along your Region/AWS Account ID information.