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

# Unity Catalog Managed Iceberg Table on AWS

This guide describes how to prepare a Databricks Unity Catalog for use with StreamNative Ursa as a managed Iceberg table catalog on AWS.

## Prerequisites

* A Databricks account with Unity Catalog and Iceberg Managed Table enabled
* An AWS account with permissions to create S3 buckets and IAM roles

## 1. Create an S3 Bucket

In your AWS account, create an S3 bucket to use as the Unity Catalog storage location (for example, `aws-unitycatalog-iceberg-bucket`).

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-01.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=16a8d80e251583c260288ea35818b51a" alt="Create S3 bucket" width="1920" height="954" data-path="images/ursa-lakehouse/uc-iceberg-aws-01.webp" />

## 2. Create the IAM Role

### 2.1 Create the Role with a Placeholder Trust Policy

Create an IAM role that allows the Unity Catalog master role to assume it. Use the following trust policy with a placeholder `External ID` of `0000` (you will replace it with the value generated by Databricks in step 3):

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": ["arn:aws:iam::414351767826:role/unity-catalog-prod-UCMasterRole-14S5ZJVKOTYTL"]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "0000"
        }
      }
    }
  ]
}
```

Skip the permissions policy on this screen -- it will be added in the next steps.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-02.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=936a123107081285f97a74fb4224d404" alt="Create IAM role" width="1920" height="916" data-path="images/ursa-lakehouse/uc-iceberg-aws-02.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-03.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=b21f4a37c97649ef67a846898de991ec" alt="Save IAM role" width="1920" height="1045" data-path="images/ursa-lakehouse/uc-iceberg-aws-03.webp" />

### 2.2 Attach the S3 Access Policy

Create the following policy and attach it to the role. Replace `<your-bucket>` and `<your-account-id>` with your values.

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload"
      ],
      "Resource": [
        "arn:aws:s3:::<your-bucket>/*",
        "arn:aws:s3:::<your-bucket>"
      ]
    },
    {
      "Effect": "Allow",
      "Action": ["sts:AssumeRole"],
      "Resource": ["arn:aws:iam::<your-account-id>:role/<your-role-name>"]
    }
  ]
}
```

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-04.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=58d4642f2c2a82a447b5dbccefdfdfc9" alt="S3 access policy" width="1920" height="986" data-path="images/ursa-lakehouse/uc-iceberg-aws-04.webp" />

### 2.3 Attach the File Events Policy

Create a second policy for managed file events (S3 notifications, SNS, SQS) and attach it to the same role:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ManagedFileEventsSetupStatement",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketNotification",
        "s3:PutBucketNotification",
        "sns:ListSubscriptionsByTopic",
        "sns:GetTopicAttributes",
        "sns:SetTopicAttributes",
        "sns:CreateTopic",
        "sns:TagResource",
        "sns:Publish",
        "sns:Subscribe",
        "sqs:CreateQueue",
        "sqs:DeleteMessage",
        "sqs:ReceiveMessage",
        "sqs:SendMessage",
        "sqs:GetQueueUrl",
        "sqs:GetQueueAttributes",
        "sqs:SetQueueAttributes",
        "sqs:TagQueue",
        "sqs:ChangeMessageVisibility",
        "sqs:PurgeQueue"
      ],
      "Resource": [
        "arn:aws:s3:::<your-bucket>",
        "arn:aws:sqs:*:*:csms-*",
        "arn:aws:sns:*:*:csms-*"
      ]
    },
    {
      "Sid": "ManagedFileEventsListStatement",
      "Effect": "Allow",
      "Action": [
        "sqs:ListQueues",
        "sqs:ListQueueTags",
        "sns:ListTopics"
      ],
      "Resource": [
        "arn:aws:sqs:*:*:csms-*",
        "arn:aws:sns:*:*:csms-*"
      ]
    },
    {
      "Sid": "ManagedFileEventsTeardownStatement",
      "Effect": "Allow",
      "Action": [
        "sns:Unsubscribe",
        "sns:DeleteTopic",
        "sqs:DeleteQueue"
      ],
      "Resource": [
        "arn:aws:sqs:*:*:csms-*",
        "arn:aws:sns:*:*:csms-*"
      ]
    }
  ]
}
```

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-05.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=630129b4af5a67272a9bc01552d29457" alt="File events policy" width="1920" height="970" data-path="images/ursa-lakehouse/uc-iceberg-aws-05.webp" />

Verify that both policies are attached to the role.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-06.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=cfc8461dc8f9c45c658cfb0e053f9d5f" alt="Attach policies to role" width="1920" height="839" data-path="images/ursa-lakehouse/uc-iceberg-aws-06.webp" />

## 3. Create an External Location in Unity Catalog

In the Databricks Catalog console, create a new external location pointing to the S3 bucket and the IAM role created above.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-07.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=6f1f55047100f372cfb6960800d2e7aa" alt="Create external location" width="1920" height="1013" data-path="images/ursa-lakehouse/uc-iceberg-aws-07.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-08.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=cde4b19d0aaa96e02ddf1298214cafb9" alt="External location settings" width="1920" height="1040" data-path="images/ursa-lakehouse/uc-iceberg-aws-08.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-09.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=50f20ac3aaf212ed47fb4466ba095847" alt="External location summary" width="1920" height="1096" data-path="images/ursa-lakehouse/uc-iceberg-aws-09.webp" />

When you submit the form, Databricks generates an **External ID** and a trust policy. Copy these values.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-10.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=9c1a403428ced8d8cedc8e088514aa18" alt="Generated External ID" width="1920" height="1054" data-path="images/ursa-lakehouse/uc-iceberg-aws-10.webp" />

## 4. Update the IAM Role Trust Policy

Return to the AWS IAM console and replace the role's trust policy with the one generated by Databricks in step 3, using the new External ID.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-11.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=8212dc2b7695215623fe090dfc6e5e98" alt="Update trust policy" width="1920" height="938" data-path="images/ursa-lakehouse/uc-iceberg-aws-11.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-12.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=102449bb4f7ef5d5b59fc7423c2468f7" alt="Trust policy applied" width="1920" height="986" data-path="images/ursa-lakehouse/uc-iceberg-aws-12.webp" />

After saving the trust policy, click **IAM role configured** in the Databricks catalog console and then **Test connection** to verify the credential.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-13.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=de3d23f701296f79993c8587c61927b3" alt="Test connection" width="1920" height="854" data-path="images/ursa-lakehouse/uc-iceberg-aws-13.webp" />

## 5. Create the Unity Catalog

Create a new catalog in Databricks bound to the external location created in step 3:

* **Type:** Standard
* **Storage location:** the external location created above

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-14.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=78db211c61bbf8702518d04c89118719" alt="Create catalog" width="1920" height="927" data-path="images/ursa-lakehouse/uc-iceberg-aws-14.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-15.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=a134748a2574b1da9a8e82e22993e414" alt="Select Standard type" width="1920" height="911" data-path="images/ursa-lakehouse/uc-iceberg-aws-15.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-16.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=930a2017881332c7910d042157736ed4" alt="Select external location" width="1920" height="955" data-path="images/ursa-lakehouse/uc-iceberg-aws-16.webp" />

## 6. Grant Catalog Permissions

Grant permissions on the catalog. The `EXTERNAL_USE_SCHEMA` permission is **required** for Iceberg Managed Tables in Unity Catalog.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-17.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=270073629053ce66810c73b89e4aea9b" alt="Grant permissions" width="1920" height="682" data-path="images/ursa-lakehouse/uc-iceberg-aws-17.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-18.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=ec7ea90e848f6b5a8afe8168d260013e" alt="EXTERNAL_USE_SCHEMA permission" width="1920" height="1065" data-path="images/ursa-lakehouse/uc-iceberg-aws-18.webp" />

## 7. Create OAuth2 Credentials

Create an OAuth2 service principal that StreamNative Ursa will use to authenticate against Unity Catalog.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-19.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=8de39b4ece9baa12079455d46075f850" alt="OAuth2 setup" width="1920" height="951" data-path="images/ursa-lakehouse/uc-iceberg-aws-19.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-20.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=0fe00bae03e58d403ba20ed288e3a78c" alt="OAuth2 setup" width="1920" height="760" data-path="images/ursa-lakehouse/uc-iceberg-aws-20.webp" />

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-21.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=19af7edcc76cbcaa4d648a7323732569" alt="OAuth2 setup" width="1920" height="731" data-path="images/ursa-lakehouse/uc-iceberg-aws-21.webp" />

Generate a secret for the principal and record both the **Client ID** and **Client Secret**.

<img src="https://mintcdn.com/streamnative/X17SyiKppfiqQD9i/images/ursa-lakehouse/uc-iceberg-aws-22.webp?fit=max&auto=format&n=X17SyiKppfiqQD9i&q=85&s=1a6e212c286bbd14ebadecc99f48b060" alt="Generate secret" width="1920" height="710" data-path="images/ursa-lakehouse/uc-iceberg-aws-22.webp" />

## 8. Enable External Data Access on the Metastore

This step is **required** for Unity Catalog Iceberg Managed Tables. Enable **External data access** on the metastore in Databricks.

<img src="https://mintcdn.com/streamnative/x2q9Vy9571owFXU5/images/ursa-lakehouse/uc-iceberg-aws-23.webp?fit=max&auto=format&n=x2q9Vy9571owFXU5&q=85&s=76f365694e6d0eb09d931fef988711aa" alt="Enable external data access" width="1920" height="746" data-path="images/ursa-lakehouse/uc-iceberg-aws-23.webp" />

<img src="https://mintcdn.com/streamnative/x2q9Vy9571owFXU5/images/ursa-lakehouse/uc-iceberg-aws-24.webp?fit=max&auto=format&n=x2q9Vy9571owFXU5&q=85&s=89d68dde15f0c77a82b4c9466d4a6bd2" alt="External data access enabled" width="1920" height="834" data-path="images/ursa-lakehouse/uc-iceberg-aws-24.webp" />

## Catalog Information Summary

When the steps above are complete, collect the following values for the StreamNative Ursa compaction service:

| Value      | Description                                                                                                 |
| ---------- | ----------------------------------------------------------------------------------------------------------- |
| URI        | Databricks workspace URL (e.g., `https://dbc-xxxx.cloud.databricks.com/api/2.1/unity-catalog/iceberg-rest`) |
| Warehouse  | The Unity Catalog name created in step 5                                                                    |
| Credential | `<client-id>:<client-secret>` from step 7                                                                   |

For the next steps, see [Configure Lakehouse Catalogs](../../../configure-lakehouse-catalogs).
