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

# Bring Your Own Cloud on AWS

> Prerequisites, IAM access, and provisioning steps for deploying Paradime BYOC inside your own AWS account, managed by the Paradime Operator.

With Bring Your Own Cloud (BYOC) on AWS, all the components that interact with your private data are deployed on your own AWS infrastructure and managed by the Paradime Control Plane via the Paradime Operator. This page provides step-by-step instructions for deploying Paradime BYOC on AWS.

<Note>
  BYOC is available on the [Enterprise plan](https://www.paradime.io/pricing). Contact the Paradime team at [support@paradime.io](mailto:support@paradime.io) for details.
</Note>

## Prerequisites

The bulk of the provisioning work is done remotely by Paradime automation. However, to get started, you need to provide Paradime with the necessary access along with some additional information:

* **AWS Account ID:** The AWS account ID of the target deployment account, available in the [AWS Console](https://console.aws.amazon.com/).
* **AWS Region:** The [AWS region](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions) where the BYOC resources should be deployed.
* **Route53 hosted zone:** A public [Route53 hosted zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html) for the DNS name your Paradime deployment will live under (for example `paradime.example.com`). Paradime creates DNS records for the application endpoints in this zone and uses it for TLS certificate validation. Pass the **Hosted Zone ID** to your Paradime contact.

In addition, make sure you have sufficient access to create the `ParadimeBYOC` IAM role that allows Paradime to:

* Create and manage a VPC
* Create one or more EKS clusters
* Create and maintain necessary IAM roles and policies
* Configure VPC networking
* Run EC2 instances
* Manage EC2 autoscaling
* Manage S3 buckets
* Manage CloudWatch Logs
* Create and manage RDS PostgreSQL instances
* Create and manage ElastiCache Redis instances
* Create and manage FSx for OpenZFS file systems
* Create and manage a DynamoDB table
* Request and validate ACM certificates
* Create DNS records in your Route53 hosted zone
* Create and manage Lambda functions, EventBridge rules, and SNS topics used for operational automation

<Warning>
  **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 Paradime creates it during provisioning. However, 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:

  ```text theme={"system"}
  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 Paradime access. `InvalidInput: ... has been taken in this account` means the role already exists and no action is needed.

  ```bash theme={"system"}
  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 Paradime during provisioning. Ask your AWS organization administrator to permit `iam:CreateServiceLinkedRole` for `rds.amazonaws.com` in this account.
</Warning>

## Provisioning access

### Create a ParadimeBYOC policy

Navigate to **IAM -> Policies** and create a new policy called `ParadimeBYOC` with the following JSON content. Substitute `{AWS_ACCOUNT_ID}` with your actual account ID and `{HOSTED_ZONE_ID}` with the ID of the Route53 hosted zone from the prerequisites.

```json theme={"system"}
{
    "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:::paradime-*"]
        },
        {
            "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": "Paradime"
                }
            }
        },
        {
            "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/Paradime*",
                "arn:aws:iam::{AWS_ACCOUNT_ID}:instance-profile/paradime-*",
                "arn:aws:iam::{AWS_ACCOUNT_ID}:oidc-provider/oidc.eks.*",
                "arn:aws:iam::{AWS_ACCOUNT_ID}:policy/Paradime*",
                "arn:aws:iam::{AWS_ACCOUNT_ID}:policy/paradime-*",
                "arn:aws:iam::{AWS_ACCOUNT_ID}:role/Paradime*",
                "arn:aws:iam::{AWS_ACCOUNT_ID}:role/paradime-*"
            ],
            "Condition": {
                "StringEquals": {
                    "iam:ResourceTag/Created-By": "Paradime"
                }
            }
        },
        {
            "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": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": ["eks:*", "kms:*"],
            "Resource": ["*"],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": ["ec2:*"],
            "Resource": ["*"],
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Created-By": "Paradime"
                }
            }
        },
        {
            "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": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets",
                "route53:GetHostedZone",
                "route53:ListResourceRecordSets",
                "route53:ListTagsForResource"
            ],
            "Resource": ["arn:aws:route53:::hostedzone/{HOSTED_ZONE_ID}"]
        },
        {
            "Effect": "Allow",
            "Action": ["route53:GetChange"],
            "Resource": ["arn:aws:route53:::change/*"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "acm:RequestCertificate",
                "acm:AddTagsToCertificate"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "acm:DescribeCertificate",
                "acm:ListTagsForCertificate",
                "acm:DeleteCertificate"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": ["dynamodb:*"],
            "Resource": ["arn:aws:dynamodb:*:{AWS_ACCOUNT_ID}:table/paradime-*"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticache:CreateReplicationGroup",
                "elasticache:CreateCacheSubnetGroup",
                "elasticache:AddTagsToResource"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticache:Describe*",
                "elasticache:ListTagsForResource",
                "elasticache:ModifyReplicationGroup",
                "elasticache:DeleteReplicationGroup",
                "elasticache:DeleteCacheSubnetGroup"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "fsx:CreateFileSystem",
                "fsx:TagResource"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "fsx:DescribeFileSystems",
                "fsx:ListTagsForResource",
                "fsx:UpdateFileSystem",
                "fsx:DeleteFileSystem"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Created-By": "Paradime"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": ["lambda:*"],
            "Resource": ["arn:aws:lambda:*:{AWS_ACCOUNT_ID}:function:paradime-*"]
        },
        {
            "Effect": "Allow",
            "Action": [
                "events:PutRule",
                "events:PutTargets",
                "events:DescribeRule",
                "events:ListTargetsByRule",
                "events:ListTagsForResource",
                "events:TagResource",
                "events:RemoveTargets",
                "events:DeleteRule"
            ],
            "Resource": ["arn:aws:events:*:{AWS_ACCOUNT_ID}:rule/paradime-*"]
        },
        {
            "Effect": "Allow",
            "Action": ["sns:*"],
            "Resource": ["arn:aws:sns:*:{AWS_ACCOUNT_ID}:paradime-*"]
        }
    ]
}
```

Most creation and modification actions are scoped by the `Created-By: Paradime` resource tag, a `paradime-` name prefix, or both. DNS access is limited to the single hosted zone you nominate. This follows the principle of least privilege and creates a clear boundary between Paradime-managed and customer-managed infrastructure within the same account.

### Create a ParadimeBYOC role

<Info>
  Reach out to the Paradime team at [support@paradime.io](mailto:support@paradime.io) to get the **Paradime BYOC provisioner account ID** and the **external ID** used below.
</Info>

Navigate to **IAM -> Roles** and create a new role called `ParadimeBYOC`. Select **AWS Account** as the trusted entity type and enter `arn:aws:iam::{PARADIME_PROVISIONER_ACCOUNT_ID}:root`, which is the Paradime BYOC provisioner account. On the **Add permissions** page, find and select the `ParadimeBYOC` policy you created earlier. On the final **Review and create** page, edit the **Trust Policy** to make it look like this:

```json theme={"system"}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{PARADIME_PROVISIONER_ACCOUNT_ID}:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "sts:ExternalId": "{PARADIME_EXTERNAL_ID}"
                }
            }
        }
    ]
}
```

Make sure to include the `sts:ExternalId` condition. The external ID acts as an additional authentication factor that prevents unauthorized parties from asking Paradime to assume your role.

## Deployment

The actual deployment is done by Paradime automation. It provisions the VPC and networking, EKS clusters and node groups, IAM roles and instance profiles, RDS PostgreSQL instances, ElastiCache Redis, FSx for OpenZFS, a DynamoDB table, S3 buckets, CloudWatch Logs delivery, KMS keys, ACM certificates, and DNS records in your hosted zone, all tagged with `Created-By: Paradime`.

All that's left to do is notify your Paradime contact at [support@paradime.io](mailto:support@paradime.io) that access has been granted, and pass along your AWS Account ID, Region, and Route53 Hosted Zone ID.


## Related topics

- [Administration](/products/settings/index.md)
- [Bring Your Own Cloud on Azure](/products/settings/deployment/byoc/azure.md)
- [Bring Your Own Cloud on GCP](/products/settings/deployment/byoc/gcp.md)
- [Deployment options](/products/settings/deployment/index.md)
- [Amazon S3](/integrations/amazon-s3.md)
