Skip to content

Commit

Permalink
feat: Added examples support (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: amanpruthi <aman.pruthi@velotio.com>
  • Loading branch information
amanpruthi and amanpruthi committed Jun 6, 2024
1 parent 307d986 commit 1eb9693
Show file tree
Hide file tree
Showing 13 changed files with 1,190 additions and 0 deletions.
37 changes: 37 additions & 0 deletions examples/custom-tf-with-existing-resources/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Azure custom terraform deployment : an existing VPC & pre-created subnets, connecting to an existing MySQL cluster, using an existing AKS cluster, and an existing Redis.

This example can be used to create the Azure Blob Ctorage container required when using the BYOB mode for Dedicated Cloud deployment.

1. Make sure you have Terraform installed
2. Make sure you have Azure CLI installed and configured
3. Clone this repository
4. Access the directory `examples/custom-tf-with-existing-resources` and fix the options in the file `terraform.tfvars`

Once the configuration is done, just execute the Terraform following the example below

```bash
terraform init
terraform apply -var-file=terraform.tfvars
```

At the end of execution you will have the following output

```bash
vpc_name = "test-vpc"
private_subnet = "private-subnet-test"
public_subnet = "public-subnet-test"
aks_cluster_name = "aks-cluster-test"
identity_name = "identity-name"
vault_uri = "vault-url"
database_env = {
host = "**.mysql.database.azure.com"
username = "**"
password = "**"
database_name = "**" }
redis_env = {
hostname = "**"
primary_access_key = "**"
port = "6379" }

```
32 changes: 32 additions & 0 deletions examples/custom-tf-with-existing-resources/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
data "azurerm_subscription" "current" {}

data "azurerm_virtual_network" "network" {
name = var.vpc_name
resource_group_name = var.namespace
}

data "azurerm_subnet" "public" {
name = var.public_subnet
virtual_network_name = var.vpc_name
resource_group_name = var.namespace
}

data "azurerm_subnet" "private" {
name = var.private_subnet
virtual_network_name = var.vpc_name
resource_group_name = var.namespace
}

data "azurerm_resource_group" "group" {
name = var.namespace
}

data "azurerm_kubernetes_cluster" "cluster" {
name = var.aks_cluster_name
resource_group_name = var.namespace
}

data "azurerm_user_assigned_identity" "identity" {
name = var.identity_name
resource_group_name = var.namespace
}
178 changes: 178 additions & 0 deletions examples/custom-tf-with-existing-resources/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
provider "azurerm" {
subscription_id = var.subscription_id
features {}
}


provider "kubernetes" {
host = data.azurerm_kubernetes_cluster.cluster.kube_config.0.host
cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.cluster_ca_certificate)
client_key = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.client_key)
client_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.client_certificate)
}

provider "helm" {
kubernetes {
host = data.azurerm_kubernetes_cluster.cluster.kube_config.0.host
cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.cluster_ca_certificate)
client_key = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.client_key)
client_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config.0.client_certificate)
}
}


locals {
fqdn = var.subdomain == null ? var.domain_name : "${var.subdomain}.${var.domain_name}"
url_prefix = var.ssl ? "https" : "http"
url = "${local.url_prefix}://${local.fqdn}"
network = data.azurerm_virtual_network.network
private_subnet = data.azurerm_subnet.private
public_subnet = data.azurerm_subnet.public
resource_group = data.azurerm_resource_group.group
vault_uri = var.vault_uri
identity_id = data.azurerm_user_assigned_identity.identity.client_id
}


module "storage" {
count = (var.blob_container == "" && var.external_bucket == null) ? 1 : 0
source = "../../modules/storage"

namespace = var.namespace
resource_group_name = local.resource_group.name
location = local.resource_group.location
create_queue = !var.use_internal_queue
deletion_protection = var.deletion_protection

tags = var.tags
}

locals {
container_name = try(module.storage[0].container.name, "")
account_name = try(module.storage[0].account.name, "")
access_key = try(module.storage[0].account.primary_access_key, "")
queue_name = try(module.storage[0].queue.name, "")
blob_container = var.external_bucket == null ? coalesce(var.blob_container, local.container_name) : ""
storage_account = var.external_bucket == null ? coalesce(var.storage_account, local.account_name) : ""
storage_key = var.external_bucket == null ? coalesce(var.storage_key, local.access_key) : ""
bucket = "az://${local.storage_account}/${local.blob_container}"
queue = (var.use_internal_queue || var.blob_container == "" || var.external_bucket == null) ? "internal://" : "az://${local.account_name}/${local.queue_name}"

redis_connection_string = "redis://:${var.redis_env.primary_access_key}@${var.redis_env.hostname}:${var.redis_env.port}"
}

locals {
service_account_name = "wandb-app"
}

resource "azurerm_federated_identity_credential" "app" {
parent_id = data.azurerm_user_assigned_identity.identity.id
name = "${var.namespace}-app-credentials"
resource_group_name = local.resource_group.name
audience = ["api://AzureADTokenExchange"]
issuer = data.azurerm_kubernetes_cluster.cluster.oidc_issuer_url
subject = "system:serviceaccount:default:${local.service_account_name}"
}

module "cert_manager" {
source = "../../modules/cert_manager"
namespace = var.namespace

ingress_class = "azure/application-gateway"
cert_manager_email = "sysadmin@wandb.com"
cert_manager_chart_version = "v1.9.1"
tags = var.tags

depends_on = [data.azurerm_kubernetes_cluster.cluster]
}

module "wandb" {
source = "wandb/wandb/helm"
version = "1.2.0"

depends_on = [
data.azurerm_kubernetes_cluster.cluster,
module.cert_manager,
module.storage,
]
operator_chart_version = "1.1.2"
controller_image_tag = "1.10.1"

spec = {
values = {
global = {
host = local.url
license = var.license

bucket = var.external_bucket == null ? {
provider = "az"
name = local.storage_account
path = local.blob_container
accessKey = local.storage_key
} : var.external_bucket

mysql = {
host = var.database_env.host
database = var.database_env.database_name
user = var.database_env.username
password = var.database_env.password
port = 3306
}

redis = {
host = var.redis_env.hostname
password = var.redis_env.primary_access_key
port = var.redis_env.port
}

extraEnv = var.other_wandb_env

}

app = {
extraEnv = merge({
"GORILLA_CUSTOMER_SECRET_STORE_AZ_CONFIG_VAULT_URI" = local.vault_uri,
"GORILLA_CUSTOMER_SECRET_STORE_SOURCE" = "az-secretmanager://wandb",
}, var.app_wandb_env)
pod = {
labels = { "azure.workload.identity/use" = "true" }
}
serviceAccount = {
name = local.service_account_name
annotations = { "azure.workload.identity/client-id" = local.identity_id}
labels = { "azure.workload.identity/use" = "true" }
}
}

ingress = {
// TODO: For now we will use the existing issuer. We can move this into
// the operator after testing. Trying to reduce the diff.
issuer = { create = false }

annotations = {
"kubernetes.io/ingress.class" = "azure/application-gateway"
"cert-manager.io/cluster-issuer" = "cert-issuer"
"cert-manager.io/acme-challenge-type" = "http01"
}

tls = [
{ hosts = [trimprefix(trimprefix(local.url, "https://"), "http://")], secretName = "wandb-ssl-cert" }
]
}

weave = {
persistence = {
provider = "azurefile"
}
extraEnv = var.weave_wandb_env
}

mysql = { install = false }
redis = { install = false }

parquet = {
extraEnv = var.parquet_wandb_env
}
}
}
}
9 changes: 9 additions & 0 deletions examples/custom-tf-with-existing-resources/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "fqdn" {
value = local.fqdn
description = "The FQDN to the W&B application"
}

output "url" {
value = local.url
description = "The URL to the W&B application"
}
Loading

0 comments on commit 1eb9693

Please sign in to comment.