# Nutanix AHV Deployment

### **Prerequisites**

1. Ensure you have access to your Nutanix AHV cluster.
2. Install the following tools on your workstation:
   * **Helm:** [Install Helm](https://helm.sh/docs/intro/install/)
   * **Kubectl:** [Install Kubectl](https://kubernetes.io/docs/tasks/tools/)
   * **AWS CLI:** [Install AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
   * **Nutanix Prism Central or Karbon CLI Tools** for managing Nutanix resources.

### **Step 1: Kubernetes Cluster Requirements**

Set up a Kubernetes cluster on Nutanix. [Nutanix Kubernetes Engine docs here](https://portal.nutanix.com/page/documents/details?targetId=Nutanix-Kubernetes-Engine-v2_10:top-deploy-kubernetes-cluster-t.html).

* The cluster must meet the following minimum requirements:
  * **Node Requirements:** 3 nodes, [each with at least 8GB of RAM](https://portal.nutanix.com/page/documents/solutions/details?targetId=NVD-2174-Hybrid-Cloud-6-5-Mid-Market-Design:virtual-machine-standard-deployment-sizes.html).

### **Step 2: Configure Persistent Storage**

Nutanix AHV uses the [Nutanix CSI](https://opendocs.nutanix.com/openshift/operators/csi/) (Container Storage Interface) driver for Kubernetes to manage persistent storage. Install and configure the CSI driver:

1. Install the Nutanix CSI driver for Kubernetes following the [Nutanix CSI documentation](https://portal.nutanix.com/page/documents/details?targetId=Nutanix-Data-Services-for-Kubernetes-v1_2:top-csi-driver-install-k8s-c.html).
2. Create a default StorageClass in Kubernetes for dynamic provisioning:

   ```yaml
   kind: StorageClass
   apiVersion: storage.k8s.io/v1
   metadata:
     name: nutanix-sc
   provisioner: csi.nutanix.com
   parameters:
     csi.storage.k8s.io/fstype: ext4
   ```

### **Step 3: Configure Kubernetes Networking**

Ensure an ingress controller is installed for external access to your services.

1. Initialize the Ingress-Nginx repository:

   ```bash
   helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
   ```
2. Deploy the Ingress-Nginx Helm chart:

   ```bash
   helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
     --namespace ingress-nginx \
     --create-namespace \
     --set controller.replicaCount=2 \
     --set controller.allowSnippetAnnotations=true \
     --set controller.ingressClassResource.default=true \
     --set force-ssl-redirect=true \
     --version=4.8.3
   ```
3. Validate that the LoadBalancer service's external IP address is configured:

   ```bash
   kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller
   ```

The Ingress-Nginx Controller is responsible for exposing application services externally to the cluster.

### **Step 4: Prepare Violet Configuration**

1. Create a `violet-values.yml` configuration file for the deployment:

   ```yaml
   domain: # The domain where Violet will be served. Subdomain must be "violet": violet.mydomain.com
   customerName: # The customer name of your license. Provided by Violet
   licenseKey: # Your license key. Provided by Violet
   adminEmail: # Admin user email for the customer
   adminName: # Admin user full name ("Firstname Lastname") for the customer

   aws:
     accessKeyId: # Leave blank or remove if not applicable
     accessKeySecret: # Leave blank or remove if not applicable

   global:
     storageClass: nutanix-sc

   # optional: This is required if you wish to use an external database 
   # instead of an internal postgres db automatically spun up by the helm chart. 
   # Do not add if using the internal db. 
   postgresql:
     enabled: false # Disable internal database if using an external database
     auth:
       host: # hostname for external db
       password: # db user password
       username: # db user username
       adminPassword: # admin user password
       adminUsername: # admin username
   ```

<details>

<summary>Deploying or Updating Version-Locked Violet [OPTIONAL]</summary>

If you would like to lock the version of Violet that you are using and not automatically pull the latest version, add the following entry to your `violet-values.yml` file:

```yaml
image:
  versionTag: # use correct version tag to lock a version and not always pull latest. Provided by Violet for initial deployment.
```

Violet changelog (& version tags) can be found here [VioletLabs changelog | Productlane](https://changelog.violetlabs.com/changelog)

If you are deploying Violet in this environment for the first time, continue to [#step-5-fetch-internal-secrets-from-violet](#step-5-fetch-internal-secrets-from-violet "mention").

If you have already deployed Violet and are just locking the version or updating to a specific version of Violet, enter that versionTag in the `violet-values.yml` file and then skip to [#step-6-deploy-violet-helm-chart](#step-6-deploy-violet-helm-chart "mention").

</details>

### **Step 5: Fetch Internal Secrets from Violet**

For managing secrets securely on Nutanix, you can use **Kubernetes Secrets** or integrate with Nutanix Vault or HashiCorp Vault. This is used to load some customer-specific secrets from the Violet AWS cloud into the On-Prem Violet Deployment.

1. Install External Secrets:

   ```bash
   helm repo add external-secrets https://charts.external-secrets.io
   helm repo update
   helm upgrade --namespace external-secrets --create-namespace --install --wait external-secrets external-secrets/external-secrets
   ```
2. Set up an AWS profile called `violet-external`&#x20;

   ```
   $ aws configure —profile violet-external
   AWS Access Key ID [None]:[AWS_ACCESS_KEY from 1Pass]
   AWS Secret Access Key [None]: [AWS_SECRET_ACCESS_KEY from 1Pass]
   Default region name [None]: us-west-1
   Default output format [None]: json
   ```
3. Create a namespace for Violet:

   ```bash
   kubectl create namespace violet
   ```
4. Create a secret that allows Kubernetes to access the Violet Helm Chart repository:

   <pre class="language-bash"><code class="lang-bash"><strong>kubectl create secret docker-registry --namespace violet ecr-creds --docker-server=911167899009.dkr.ecr.us-west-1.amazonaws.com --docker-username=AWS --docker-password=$(aws ecr --profile violet-external get-login-password)
   </strong></code></pre>
5. Install the mezmo logging agent. This streams logs from your cluster to the violet team for troubleshooting and monitoring assistance

   ```
   kubectl apply -f https://assets.logdna.com/clients/logdna-agent/3/agent-namespace.yaml

   # Get <mezmo-ingestion-key> from your 1Pass entry
   kubectl create secret generic logdna-agent-key -n logdna-agent --from-literal=logdna-agent-key=<mezmo-ingestion-key> 

   kubectl apply -f https://assets.logdna.com/clients/logdna-agent/3/agent-resources.yaml
   ```

### **Step 6: Deploy Violet Helm Chart**

1. Log into the Violet Helm Chart Repository

   ```bash
   aws ecr --profile violet-external get-login-password | helm registry login --username AWS --password-stdin 911167899009.dkr.ecr.us-west-1.amazonaws.com
   ```
2. Install the Violet Helm Chart:

   ```bash
   helm upgrade --namespace violet --create-namespace --install myviolet oci://911167899009.dkr.ecr.us-west-1.amazonaws.com/violet-helm --version 1.0.0-main -f violet-values.yml
   ```

### **Step 7: Verify Installation**

Note that it may take up to 5 minutes to run the database provisioning scripts. You can check the status of the deployment by looking at the pods:

1. Check the status of the pods in the Violet namespace:

   ```bash
   kubectl get pods -n violet
   ```

### **Step 8: Post-Installation Configuration**

After installation is complete the helm chart will print our some information and commands including the URL to access your new deployment, how to get the IP Address that the deployment is served at (for setting up DNS rules) and how to obtain the auto-generated password for the `violet_admin@violetlabs.com` account.
