diff --git a/oracle/README.md b/oracle/README.md new file mode 100644 index 0000000..b586849 --- /dev/null +++ b/oracle/README.md @@ -0,0 +1,30 @@ +# Qdrant Hybrid Cloud Example for Oracle Cloud + +Example how to use Oracle k8s cluster as private region for hybrid qdrant cloud. + +### Apply terraform +This terraform code is for a basic VPC and k8s cluster setup in a Oracle project. +It is used for Qdrant Cloud hybrid vector database setup example. +- Go to `terraform` folder and run: + - `terraform init` + - `terraform apply` + +### Setup Private region +After cluster is ready login to https://cloud.qdrant.io/ +- Go to "Private regions" +- Create a "Private region", pick a name and a Kubernetes namespace. All other settings should be able to stay as default +- Click 'Generate installation Command' button. It will generate `kubectl` and `helm` commands like this: +``` bash +kubectl create namespace delete-me +kubectl --namespace delete-me create secret docker-registry qdrant-registry-creds +kubectl --namespace delete-me create secret generic qdrant-cloud-creds --from-literal=access-key='*' +helm install qdrant-cloud-agent +``` +- Execute this against the created Kubernetes cluster to deploy the Qdrant cloud agent and Qdrant operator +- The agent should connect back to Qdrant cloud, install the operator and report back a healthy status +- Now you can create a cluster within this new region + - The cluster should report back as healthy + - Note: make sure your k8s node pool match with qdrant cluster size you request + + + diff --git a/oracle/terraform/cluster.tf b/oracle/terraform/cluster.tf new file mode 100644 index 0000000..8f151df --- /dev/null +++ b/oracle/terraform/cluster.tf @@ -0,0 +1,32 @@ +resource "oci_containerengine_cluster" "oke_cluster" { + name = var.cluster_name + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + kubernetes_version = var.kubernetes_version + + options { + service_lb_subnet_ids = [oci_core_subnet.oke_subnet1.id, oci_core_subnet.oke_subnet2.id] + } +} + +resource "oci_containerengine_node_pool" "node_pool" { + cluster_id = oci_containerengine_cluster.oke_cluster.id + compartment_id = oci_identity_compartment.oke_compartment.id + kubernetes_version = var.kubernetes_version + name = var.nodepool_name + node_shape = var.oci_node_pool_node_shape + subnet_ids = [oci_core_subnet.nodePool_Subnet_1.id, oci_core_subnet.nodePool_Subnet_2.id] + + initial_node_labels { + key = "key" + value = "value" + } + + node_source_details { + image_id = var.oci_node_pool_node_image_name + source_type = "IMAGE" + boot_volume_size_in_gbs = "60" + } + + quantity_per_subnet = var.nodepool_quantity_per_subnet +} diff --git a/oracle/terraform/locals.tf b/oracle/terraform/locals.tf new file mode 100644 index 0000000..a83bbfd --- /dev/null +++ b/oracle/terraform/locals.tf @@ -0,0 +1,4 @@ +locals { + tenancy_ocid = var.tenancy_ocid + region = var.region +} diff --git a/oracle/terraform/providers.tf b/oracle/terraform/providers.tf new file mode 100644 index 0000000..c74ef82 --- /dev/null +++ b/oracle/terraform/providers.tf @@ -0,0 +1,7 @@ +provider "oci" { + tenancy_ocid = local.tenancy_ocid + user_ocid = var.user_ocid + fingerprint = var.fingerprint + private_key_path = var.private_key_path + region = local.region +} diff --git a/oracle/terraform/terraform.tfvars b/oracle/terraform/terraform.tfvars new file mode 100644 index 0000000..fe0e800 --- /dev/null +++ b/oracle/terraform/terraform.tfvars @@ -0,0 +1,20 @@ +tenancy_ocid = "your-tenancy-ocid" //FIXME: Replace with your tenancy OCID +region = "eu-frankfurt-1" +user_ocid = "your-user-ocid" //FIXME: Replace with your user OCID +fingerprint = "your-fingerprint" //FIXME: Replace with your fingerprint +private_key_path = "/path/to/your/private_key.pem" //FIXME: Replace with the path to your private key +oci_node_pool_node_shape = "VM.Standard2.1" +oci_node_pool_node_image_name = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaamwc7ozp4edhlcc5n76o2fjqya3auhugwpgfha3wgbk64jvx43kga" +oke_compartment_name = "OKE_Compartment" +oke_compartment_description = "Compartment for Oracle Kubernetes Engine" +oke_vcn_cidr_block = "10.0.0.0/16" +oke_subnet1_cidr_block = "10.0.1.0/24" +oke_subnet2_cidr_block = "10.0.2.0/24" +nodepool_subnet1_cidr_block = "10.0.3.0/24" +nodepool_subnet2_cidr_block = "10.0.4.0/24" +cluster_name = "my_oke_cluster" +kubernetes_version = "v1.29.1" +nodepool_name = "tfPool" +nodepool_quantity_per_subnet = 2 +security_list_display_name = "AllowAccess" + diff --git a/oracle/terraform/variables.tf b/oracle/terraform/variables.tf new file mode 100644 index 0000000..53ab450 --- /dev/null +++ b/oracle/terraform/variables.tf @@ -0,0 +1,94 @@ +variable "tenancy_ocid" { + description = "The OCID of the tenancy" + type = string +} + +variable "region" { + description = "OCI region" + type = string +} + +variable "user_ocid" { + description = "The OCID of the user" + type = string +} + +variable "fingerprint" { + description = "The fingerprint for the user's API key" + type = string +} + +variable "private_key_path" { + description = "The path to the private key for API signing" + type = string +} + +variable "oci_node_pool_node_shape" { + description = "OCI Kubernetes node pool Shape (e.g. `VM.Standard2.1` => 1vCPU, 15GB RAM)" + type = string +} + +variable "oci_node_pool_node_image_name" { + description = "OCI Kubernetes node pool image name (e.g. `Oracle-Linux-7.6`)" + type = string +} + +variable "oke_compartment_name" { + description = "Name of the compartment for Oracle Kubernetes Engine" + type = string +} + +variable "oke_compartment_description" { + description = "Description of the compartment for Oracle Kubernetes Engine" + type = string +} + +variable "oke_vcn_cidr_block" { + description = "CIDR block for the VCN" + type = string +} + +variable "oke_subnet1_cidr_block" { + description = "CIDR block for OKE Subnet 1" + type = string +} + +variable "oke_subnet2_cidr_block" { + description = "CIDR block for OKE Subnet 2" + type = string +} + +variable "nodepool_subnet1_cidr_block" { + description = "CIDR block for Node Pool Subnet 1" + type = string +} + +variable "nodepool_subnet2_cidr_block" { + description = "CIDR block for Node Pool Subnet 2" + type = string +} + +variable "cluster_name" { + description = "Name of the OKE cluster" + type = string +} + +variable "kubernetes_version" { + description = "Kubernetes version" + type = string +} + +variable "nodepool_name" { + description = "Name of the node pool" + type = string +} + +variable "nodepool_quantity_per_subnet" { + description = "Quantity of nodes per subnet in the node pool" + type = number +} + +variable "security_list_display_name" { + description = "Display name for the security list" + type = string +} diff --git a/oracle/terraform/versions.tf b/oracle/terraform/versions.tf new file mode 100644 index 0000000..90292f8 --- /dev/null +++ b/oracle/terraform/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + linode = { + source = "oracle/oci" + version = "5.43.0" + } + } + required_version = "~> 1" +} \ No newline at end of file diff --git a/oracle/terraform/vpc.tf b/oracle/terraform/vpc.tf new file mode 100644 index 0000000..7f3940a --- /dev/null +++ b/oracle/terraform/vpc.tf @@ -0,0 +1,85 @@ +resource "oci_identity_compartment" "oke_compartment" { + name = var.oke_compartment_name + description = var.oke_compartment_description + compartment_id = local.tenancy_ocid +} + +resource "oci_core_vcn" "oke_vcn" { + cidr_block = var.oke_vcn_cidr_block + display_name = "OKE_VCN" + compartment_id = oci_identity_compartment.oke_compartment.id +} + +data "oci_identity_availability_domains" "ads" { + compartment_id = local.tenancy_ocid +} + +resource "oci_core_subnet" "oke_subnet1" { + display_name = "OKE_Subnet1" + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + cidr_block = var.oke_subnet1_cidr_block + route_table_id = oci_core_vcn.oke_vcn.default_route_table_id + dhcp_options_id = oci_core_vcn.oke_vcn.default_dhcp_options_id + availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name +} + +resource "oci_core_subnet" "oke_subnet2" { + display_name = "OKE_Subnet2" + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + cidr_block = var.oke_subnet2_cidr_block + route_table_id = oci_core_vcn.oke_vcn.default_route_table_id + dhcp_options_id = oci_core_vcn.oke_vcn.default_dhcp_options_id + availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name +} + +resource "oci_core_subnet" "nodePool_Subnet_1" { + availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name + cidr_block = var.nodepool_subnet1_cidr_block + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + security_list_ids = [oci_core_vcn.oke_vcn.default_security_list_id, oci_core_security_list.security_list.id] + display_name = "tfSubNet1ForNodePool" + route_table_id = oci_core_route_table.route_table.id +} + +resource "oci_core_subnet" "nodePool_Subnet_2" { + availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name + cidr_block = var.nodepool_subnet2_cidr_block + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + security_list_ids = [oci_core_vcn.oke_vcn.default_security_list_id, oci_core_security_list.security_list.id] + display_name = "tfSubNet2ForNodePool" + route_table_id = oci_core_route_table.route_table.id +} + +resource "oci_core_internet_gateway" "ig" { + compartment_id = oci_identity_compartment.oke_compartment.id + display_name = "tfClusterInternetGateway" + vcn_id = oci_core_vcn.oke_vcn.id +} + +resource "oci_core_route_table" "route_table" { + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + display_name = "tfClustersRouteTable" + + route_rules { + destination = "0.0.0.0/0" + destination_type = "CIDR_BLOCK" + network_entity_id = oci_core_internet_gateway.ig.id + } +} + +resource "oci_core_security_list" "security_list" { + compartment_id = oci_identity_compartment.oke_compartment.id + vcn_id = oci_core_vcn.oke_vcn.id + display_name = var.security_list_display_name + + ingress_security_rules { + protocol = "All" + source = "0.0.0.0/0" + source_type = "CIDR_BLOCK" + } +} \ No newline at end of file