# Azure PrivateLink

### **What is an Azure PrivateLink?**

Azure Private Link is a feature in Microsoft Azure that enables customers to access Azure services, such as Snowflake, over a private endpoint within their virtual network.

By leveraging Azure Private Link, Snowflake users can access their data warehouse without going over the public internet, improving data security and reducing latency. With this setup, users can establish a private endpoint for Snowflake within their Azure virtual network and connect to Snowflake using private IP addresses.

### **Pre-requisites**

* An Azure subscription with permission to create a virtual network.
* An existing virtual network in Azure with a subnet that can be dedicated to the Snowflake Private Link endpoint.
* A Snowflake account with a virtual private cloud (VPC) enabled and network policies configured.
* A Snowflake user account with the `ACCOUNTADMIN` role or equivalent privileges to create a private link endpoint.
* A virtual machine or client machine with connectivity to the Azure virtual network and the ability to access the Snowflake account using a private IP address.

{% hint style="info" %}
Please note that if Tellius is hosting the infrastructure, then the Tellius team will take care of all the steps on the Azure side. Contact <support@tellius.com> for further assistance.
{% endhint %}

### **Setting up Snowflake**

**Obtain PrivateLink resource ID and accessToken from Snowflake console**

1. Log in to the Snowflake Console as the admin user
2. Open a blank worksheet and run the following command:

```sql
select SYSTEM$GET_PRIVATELINK_CONFIG() using role ACCOUNTADMIN;
```

1. Save the JSON output to be used later
2. Note down the resourceId and accessToken values from the JSON output

```sql
use role accountadmin;
select system$authorize_privatelink (
  '<resourceId>',
  '<accessToken>'
  );
```

### **Create a Private endpoint in Azure**

1. Log in to the Azure Portal.
2. Search for **Private Link** service and open it.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/UJRIYXrZXPyTPhQeTKhC/image.png" alt="" width="563"><figcaption><p>Private Link</p></figcaption></figure>

3. Click on **Private endpoints** and then on **Create**.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/RUH2UoDwmF6hWebutYLo/image.png" alt="" width="563"><figcaption><p>Private endpoints</p></figcaption></figure>

4. Enter the resource group name of the Kubernetes cluster for which it needs to be linked (for example, POC9).
5. Enter a name for the private endpoint and click on **Next**.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/9csYJtXPGqMCdO3fdr5w/image.png" alt="" width="563"><figcaption><p>Creating a private endpoint -> Basics</p></figcaption></figure>

6. Choose the option **Connect to an Azure resource by resource ID or alias.**
7. Open the saved Snowflake JSON output and copy the *privatelink-pls-id* value for Resource ID/Alias.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/3UgagkW17j8qmKJxxcUt/image.png" alt="" width="563"><figcaption><p>Creating a private endpoint -> Resource</p></figcaption></figure>

8. Click on **Next** and choose the virtual network as the same network as that of the Kubernetes cluster. The subnet will be auto-populated for the subnet of the cluster/vnet.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/oeswaSk0LkxK7myCHiaX/image.png" alt="" width="563"><figcaption><p>Creating a private endpoint -> Virtual network</p></figcaption></figure>

9. Click on **Next** until you reach the **Review and Create** page. Then click on **Create**.
10. Since the Private Endpoint is in a “**Pending**” state, and to move it to the “**Approved**” state, the following needs to be executed on Azure CLI. Note down the resource ID output from the Azure CLI command:

```bash
az network private-endpoint show --resource-group <resource-group-name> --name <private-endpoint-name>
```

### **Obtain accessToken for Private Endpoint from Azure CLI**

1. Run the following Azure CLI command to get the accessToken, and the same will be used as  `federated_token` in the next step.

```bash
az account get-access-token --subscription <subscription-id>
```

2. The output looks similar to the following:

```json
{
  "accessToken": “eyJ…<token>",
  "expiresOn": "2023-01-25 12:33:15.000000",
  "subscription": "ceb13d30-0708-43e3-bbfa-6451fa0a8b0af",
  "tenant": "da57d934d-5051-4297-89d7-af436b226ab3",
  "tokenType": "Bearer"
}
```

3. Save the JSON output to be used later. Also, note down the accessToken value from the JSON output.

### **Authorize Private Link in Snowflake**

1. Log in to the Snowflake Console as the admin user.
2. Open a blank worksheet and run the following command:

```sql
use role accountadmin;
select system$authorize_privatelink (
'<resourceId>',
'<accessToken>'
);
```

3. Replace `<resourceId>` and `<accessToken>` with the values obtained in steps 1 and 3.
4. Once done, “**Private Link is authorized**” message will be displayed.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/OzLyZb1q5jwjCEcuwcWe/image.png" alt="" width="563"><figcaption><p>“<strong>Private Link is authorized</strong>” message</p></figcaption></figure>

### **Approve Private Endpoint in Azure**

1. Run the following Azure CLI command to approve the Private Endpoint:

```bash
az network private-endpoint update --id <private-endpoint-id> --set manualApproval=Approved
```

2. Replace `<private-endpoint-id>` with the value obtained in step 2
3. Now, the Private Endpoint is in "**Approved**" state in the Azure Portal.
4. Copy the private endpoint IP as it is needed to route requests via Private DNS. (e.g., 10.240.0.5).

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/yTb5SBOgU5XL0pCIgiuc/image.png" alt="" width="563"><figcaption><p>Private endpoint IP</p></figcaption></figure>

### **Create Private DNS Zone in Azure**

1. Go to Private DNS Zones in the Azure Portal and click on **Create**.
2. Enter the name "privatelink.snowflakecomputing.com" and click on **Create**.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/YCRWOGkpjiWLrzRO1FLt/image.png" alt="" width="563"><figcaption><p>Creating private DNS</p></figcaption></figure>

### **Add Record Sets to Private DNS Zone**

1. Open the created Private DNS Zone and click on **Create record set.**
2. Enter the following details for the first record set:

* **Record type:** A
* **Name:** \<privatelink-account-url> (from the saved Snowflake JSON output)
* **IPv4 address:** \<private-endpoint-IP> (note down from the Azure Portal)
* **TTL:** 30 seconds

3. Create another record set for OCSP Cache Server using the same process

* **Record type:** A
* **Name:** \<privatelink-ocsp-url> (from the saved Snowflake JSON output)
* **IPv4 address:** \<private-endpoint-IP> (note down from the Azure Portal)
* **TTL:** 30 seconds

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/xp8Waiei28TOic4VF480/image.png" alt="" width="563"><figcaption><p>Adding record sets</p></figcaption></figure>

### **Test the Private Link Connection**

1. Use the Snowflake console to test the private link connection by running queries.
2. Verify whether the queries are running successfully.

### **Add the Virtual Network links to the Private DNS Zone**

1. Go to the **Private DNS Zone** and click on **Virtual network links**. Click on **Add**.
2. Populate the name and choose the same virtual network as that of the Kubernetes cluster that needs to be linked with. Click on **Okay** to create.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/tWtZKb0zveUfPRe1LoKZ/image.png" alt="" width="563"><figcaption><p>Adding virtual network link</p></figcaption></figure>

3. Finally, navigate to the private endpoint that you had created earlier, in the DNS Configuration section. Click on **Add configuration**.
4. Populate the values for the **Private DNS Zone** that has been created and click on **Add**.

<figure><img src="https://content.gitbook.com/content/s16h5onryWtbaHwBa10b/blobs/fvYYuAZfTPJ7bgIq40Os/image.png" alt="" width="563"><figcaption><p>Private DNS zone</p></figcaption></figure>

Users can now test the data source connection to their snowflake account.

### **Reference**

* <https://docs.snowflake.com/en/user-guide/privatelink-azure.html>&#x20;
* <https://community.snowflake.com/s/article/How-To-Set-up-Private-DNS-zone-for-Azure-Private-Link-with-Snowflake>
