# Data plane setup on AWS
> This bundle contains all pages in the Data plane setup on AWS section.
> Source: https://www.union.ai/docs/v1/union/deployment/selfmanaged/byok-data-plane-setup-on-aws/

=== PAGE: https://www.union.ai/docs/v1/union/deployment/selfmanaged/byok-data-plane-setup-on-aws ===

# Data plane setup on AWS

> **📝 Note**
>
> An LLM-optimized bundle of this entire section is available at [`section.md`](section.md).
> This single file contains all pages in this section, optimized for AI coding agent context.

To set up your Union.ai data plane on Amazon Web Services (AWS), you must allow Union.ai to provision and maintain compute resources under your AWS account.

There are two approaches to setting up your data plane:

## Recommended Approach: CDK

Use the Union.ai [EKS Blueprints addon](https://www.npmjs.com/package/@unionai/union-eks-blueprints-addon) with [AWS CDK](https://aws.amazon.com/cdk/) to automate the provisioning of your data plane infrastructure, including the EKS cluster, IAM roles, and Helm chart deployment.

> [!NOTE]
> If the CDK path does not work for you, use AWS CloudFormation or the AWS console to create the required IAM roles and permissions, follow the **Self-managed deployment > Data plane setup on AWS > Manual setup on AWS** installation steps.

### **Self-managed deployment > Data plane setup on AWS > Setup with AWS CDK**

Automate data plane provisioning with AWS CDK and EKS Blueprints

=== PAGE: https://www.union.ai/docs/v1/union/deployment/selfmanaged/byok-data-plane-setup-on-aws/cdk ===

# Setup with AWS CDK

You can automate the provisioning of your Union.ai data plane on AWS using [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/) and [EKS Blueprints](https://aws-quickstart.github.io/cdk-eks-blueprints/).

The [`@unionai/union-eks-blueprints-addon`](https://www.npmjs.com/package/@unionai/union-eks-blueprints-addon) package provides CDK constructs that deploy the Union.ai data plane onto an EKS cluster, including all required IAM roles, Helm charts, and Kubernetes resources.

## Prerequisites

- [Node.js](https://nodejs.org/) >= 18
- [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting-started.html) v2 installed and bootstrapped in your target account/region
- [npm](https://www.npmjs.com/) or another Node.js package manager
- A Union.ai organization with the following information (provided by the Union.ai team):
  - **Control plane host** (e.g. `your-org.hosted.unionai.cloud`)
  - **Organization name**
  - **Cluster name** registered with Union.ai
  - **Client ID** and **Client Secret** for authentication

## Installation

Install the addon package in your CDK project:

```bash
npm install @unionai/union-eks-blueprints-addon
```

## Store your credentials in AWS Secrets Manager

The addon retrieves Union.ai credentials from AWS Secrets Manager. Create a secret containing both the client ID and client secret as a JSON object:

```bash
aws secretsmanager create-secret \
  --name "union/credentials" \
  --secret-string '{"clientId": "<YOUR_CLIENT_ID>", "clientSecret": "<YOUR_CLIENT_SECRET>"}'
```

## Create your CDK stack

The following example creates an EKS cluster with [EKS Auto Mode](https://docs.aws.amazon.com/eks/latest/userguide/automode.html) enabled and deploys the Union.ai data plane onto it:

```typescript
import * as cdk from 'aws-cdk-lib';
import * as blueprints from "@aws-quickstart/eks-blueprints"
import * as union from "@unionai/union-eks-blueprints-addon"

const app = new cdk.App();

const account = process.env.CDK_DEFAULT_ACCOUNT;
const region = process.env.CDK_DEFAULT_REGION;
let props = { env: { account, region } };

const unionBlueprint = blueprints.AutomodeBuilder.builder({})
  .resourceProvider(
    'union-bucket',
    new blueprints.CreateS3BucketProvider({
      id: 'my-union-bucket-123',
      s3BucketProps: { bucketName: 'union-bucket' }
    })
  )
  .addOns(
    new blueprints.addons.MetricsServerAddOn(),
    new union.UnionDataplaneCRDsAddOn(),
    new union.UnionDataplaneAddOn({
      s3BucketProviderName: 'union-bucket',
      clusterName: "<YOUR_UNION_CLUSTER_NAME>",
      unionSecretName: "<YOUR_UNION_SECRET_NAME>",
      host: "<YOUR_UNION_CONTROL_PLANE_HOST>",
      orgName: "<YOUR_ORG_NAME>"
    })
  )
  .build(app, "union-blueprint", props);
```

Replace the placeholder values:

| Parameter | Description |
| --- | --- |
| `s3BucketProviderName` | Name of the S3 bucket resource provider registered with the blueprint. Must match the name passed to `resourceProvider()`. |
| `clusterName` | Name of the cluster registered with Union.ai. Provided by the Union.ai team. |
| `unionSecretName` | Name of the AWS Secrets Manager secret containing your Union.ai credentials. |
| `host` | Your Union.ai control plane URL (without `https://`). |
| `orgName` | Your Union.ai organization name. |

## Deploy

Once your CDK stack is defined, deploy it:

```bash
cdk deploy union-blueprint
```

## What gets provisioned

The addon deploys the following resources:

- **UnionDataplaneCRDsAddOn**: Installs the Union.ai Custom Resource Definitions (CRDs) required by the data plane operator.
- **UnionDataplaneAddOn**: Deploys the Union.ai data plane Helm chart, which includes:
  - An IAM policy granting read/write access to the configured S3 bucket.
  - An IAM role with OIDC federation for Kubernetes service accounts.
  - The data plane operator and supporting services.

## Using an existing S3 bucket

If you already have an S3 bucket, use `ImportS3BucketProvider` instead of `CreateS3BucketProvider`:

```typescript
.resourceProvider(
  'union-bucket',
  new blueprints.ImportS3BucketProvider('my-existing-bucket-name')
)
```

## Additional configuration

The `UnionDataplaneAddOn` accepts additional Helm values through the `values` property, which are merged with the defaults. Refer to the Union.ai Helm chart documentation for available options.

=== PAGE: https://www.union.ai/docs/v1/union/deployment/selfmanaged/byok-data-plane-setup-on-aws/manual ===

# Manual setup on AWS

Union.ai's modular architecture allows for great flexibility and control.
The customer can decide how many clusters to have, their shape, and who has access to what.
All communication is encrypted.  The Union architecture is described on the [Architecture](../architecture/_index) page.

## Assumptions

* You have a Union.ai organization, and you know the control plane URL for your organization.
* You have a cluster name provided by or coordinated with Union.
* You have a Kubernetes cluster, running one of the most recent three minor K8s versions.
  [Learn more](https://kubernetes.io/releases/version-skew-policy/)
* You have configured an S3 bucket.
* You have an IAM Role, Trust Policy and OIDC provider configured as indicated in the [AWS section in Cluster Recommendations](https://www.union.ai/docs/v1/union/deployment/selfmanaged/cluster-recommendations) section.

## Prerequisites

* Install [Helm 3](https://helm.sh/docs/intro/install/).
* Install [uctl](https://www.union.ai/docs/v1/union/deployment/api-reference/uctl-cli/_index).

## Deploy the Union.ai operator

1. Add the Union.ai Helm repo:

   ```shell
   helm repo add unionai https://unionai.github.io/helm-charts/
   helm repo update
   ```

2. Use the `uctl selfserve provision-dataplane-resources` command to generate a new client and client secret for communicating with your Union control plane, provision authorization permissions for the app to operate on the union cluster name you have selected, generate values file to install dataplane in your Kubernetes cluster and provide follow-up instructions:

   ```shell
   uctl config init --host=<YOUR_UNION_CONTROL_PLANE_URL>
   uctl selfserve provision-dataplane-resources --clusterName <YOUR_SELECTED_CLUSTERNAME>  --provider aws
   ```

   * The command will output the ID, name, and a secret that will be used by the Union services to communicate with your control plane.
     It will also generate a YAML file specific to the provider that you specify, in this case `aws`:

   ```shell
    -------------- ------------------------------------ ---------------------------- ------------------------------------------------- ------------------------------------------------------------------ ----------
   | ORGANIZATION | HOST                               | CLUSTER                    | CLUSTERAUTHCLIENTID                             | CLUSTERAUTHCLIENTSECRET                                          | PROVIDER |
    -------------- ------------------------------------ ---------------------------- ------------------------------------------------- ------------------------------------------------------------------ ----------
   | xxxxxxxxxxx  | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | xxxxxxxxxxxxxxxxxxxxxxxxxx | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | xxxxx    |
    -------------- ------------------------------------ ---------------------------- ------------------------------------------------- ------------------------------------------------------------------ ----------
   1 rows

   ✅ Generated <ORGNAME>-values.yaml
   ======================================================================
   Installation Instructions
   ======================================================================

   Step 1: Setup the infrastucture on AWS. Our team can share terrform scripts to help with this.

   Step 2: Clone and navigate to helm-charts repository
     git clone https://github.com/unionai/helm-charts && cd helm-charts

   Step 3: Ensure S3 bucket & IAM roles are configured; set role ARN(s) in values

   Step 4: Install the data plane CRDs
     helm upgrade --install unionai-dataplane-crds charts/dataplane-crds

   Step 5: Install the data plane
     helm upgrade --install unionai-dataplane charts/dataplane \
       --namespace union \
       --values <ORGNAME>-values.yaml

   Step 6: Verify installation
     kubectl get pods -n union

   Step 7: Once you have your dataplane up and running, create API keys for your organization. If you have already just call the same command again to propogate the keys to new cluster:
     uctl create apikey --keyName EAGER_API_KEY --org <your-org-name>

   Step 8: You can now trigger v2 executions on this dataplane.
   ```
   * Save the secret that is displayed. Union does not store the credentials, rerunning the same command can be used to show same secret later which stream through the OAuth Apps provider.
   * Create the `EAGER_API_KEY` as instructed in Step 7 of the command output. This step is required for every dataplane you plan to use for v2 executions.

3. Update the values file correctly:
   For example, `<UNION_FLYTE_ROLE_ARN>` is the ARN of the new IAM role created in the [AWS Cluster Recommendations](https://www.union.ai/docs/v1/union/deployment/selfmanaged/cluster-recommendations)

4. Optionally configure the resource `limits` and `requests` for the different services.
   By default, these will be set minimally, will vary depending on usage, and follow the Kubernetes `ResourceRequirements` specification.

   * `clusterresourcesync.resources`
   * `flytepropeller.resources`
   * `flytepropellerwebhook.resources`
   * `operator.resources`
   * `proxy.resources`

5. Once deployed you can check to see if the cluster has been successfully registered to the control plane:

   ```shell
   uctl get cluster
    ----------- ------- --------------- -----------
   | NAME      | ORG   | STATE         | HEALTH    |
    ----------- ------- --------------- -----------
   | <cluster> | <org> | STATE_ENABLED | HEALTHY   |
    ----------- ------- --------------- -----------
   1 rows
   ```

6. You can then register and run some example workflows through your cluster to ensure that it is working correctly.

   ```shell
   uctl register examples --project=union-health-monitoring --domain=development
   uctl validate snacks --project=union-health-monitoring --domain=development
    ---------------------- ----------------------------------- ---------- -------------------------------- -------------- ----------- ---------------
   | NAME                 | LAUNCH PLAN NAME                  | VERSION  | STARTED AT                     | ELAPSED TIME | RESULT    | ERROR MESSAGE |
    ---------------------- ----------------------------------- ---------- -------------------------------- -------------- ----------- ---------------
   | alskkhcd6wx5m6cqjlwm | basics.hello_world.hello_world_wf | v0.3.341 | 2025-05-09T18:30:02.968183352Z | 4.452440953s | SUCCEEDED |               |
    ---------------------- ----------------------------------- ---------- -------------------------------- -------------- ----------- ---------------
   1 rows
   ```

