Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/tofu-deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Infrastructure Deployment on Self Hosted Kubernetes Cluster

on:
workflow_dispatch:
push:
branches:
- task/**
- bug/**
pull_request:
branches:
- main
types:
- opened
- synchronize
- closed

concurrency:
group: deployment
cancel-in-progress: false

jobs:
infrastructure_deploy:
name: Infrastructure Deployment on Self Hosted Kubernetes Cluster
uses: necro-cloud/automations/.github/workflows/tofu-deploy.yml@main
with:
deployment_name: Kubernetes Infrastructure
folder_path: example
runners: cloud
pre_plan_script: tofu apply --target=module.helm -var-file terraform.tfvars.json -auto-approve
secrets:
KUBECONFIG: ${{ secrets.KUBECONFIG }}
TFVARS: ${{ secrets.TFVARS }}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# necronizer's cloud modules

OpenTofu Modules that can be used to deploy a functioning self hosted cloud solution perfect for side projects
OpenTofu Modules that can be used to deploy a functioning self hosted cloud solution perfect for side projects. For a guide on how to use these modules, please navigate to the [example](./example) directory.

# Requirements and Dependencies

Expand Down
21 changes: 21 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# necronizer's cloud guide to use OpenTofu modules

This directory mainly contains OpenTofu files on how to use the [modules](https://github.com/necro-cloud/modules) for deploying a self hosted cloud solution perfect for side projects and also is used for testing out modules when new features are being worked on.

# Requirements and Dependencies

The following is required to start using this repository:
1. [OpenTofu](https://opentofu.org/) - Since modules are written in OpenTofu, we deploy all components using OpenTofu
2. Kubernetes Cluster - Any kubernetes cluster can do, tested out with my [self hosted kubernetes cluster](https://github.com/necro-cloud/kubernetes)
3. [Cloudflare Token and DNS Zones](https://www.cloudflare.com/) - Currently all modules use Cloudflare for provisioning public SSL certificates using DNS01 challenge validation.
4. An SMTP Server - For sending mails using Keycloak Authentication

# Usage Instructions:

**Step 1:** Setup a TFVARS file, an example for which is given [here](terraform-example.tfvars.json) which will require SMTP Server details to be added along with [Cloudflare Token](https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/#api-tokens) and DNS to be used. Save the file as `terraform.tfvars.json`.

**Step 2:** Initialize the state with OpenTofu by running the following command: `tofu init`

**Step 3:** Deploy all required CRDs using OpenTofu by executing the following command: `tofu apply --target=module.helm -var-file terraform.tfvars.json -auto-approve`

**Step 4:** Now you can deploy all components using OpenTofu by executing the following command: `tofu apply -var-file terraform.tfvars.json -auto-approve`
14 changes: 14 additions & 0 deletions example/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
locals {
keycloak_realm_settings = {
display_name = "Necronizer's Cloud"
application_name = "cloud"
base_url = var.keycloak_authentication_base_url
valid_login_redirect_path = var.keycloak_authentication_valid_login_redirect_path
valid_logout_redirect_path = var.keycloak_authentication_valid_logout_redirect_path
smtp_host = var.smtp_host
smtp_port = var.smtp_port
smtp_mail = var.smtp_mail
smtp_username = var.smtp_username
smtp_password = var.smtp_password
}
}
115 changes: 115 additions & 0 deletions example/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Fetch the Kubernetes API Endpoint to be used for whitelisting by other modules
data "kubernetes_endpoints_v1" "kubernetes_api_endpoint" {
metadata {
name = "kubernetes"
namespace = "default"

}
}

# Deploy all required helm charts for deploying the infrastructure
module "helm" {
source = "git::https://github.com/necro-cloud/modules//modules/helm?ref=main"
server_node_selector = "cloud"
}

# Setup a Cluster Issuer for all private TLS certificates
module "cluster-issuer" {
source = "git::https://github.com/necro-cloud/modules//modules/cluster-issuer?ref=main"

depends_on = [module.helm]
}

# Garage Deployment for an S3 compatible object storage solution
module "garage" {
source = "git::https://github.com/necro-cloud/modules//modules/garage?ref=main"

// Certificates Details
cluster_issuer_name = module.cluster-issuer.cluster-issuer-name
cloudflare_token = var.cloudflare_token
cloudflare_email = var.cloudflare_email
domain = var.domain

// Granting required namespaces access to the Garage cluster
access_namespaces = "postgres"

// Configuring required configurations on the Garage Cluster
required_buckets = var.garage_required_buckets
required_access_keys = var.garage_required_access_keys

// Whitelisting Kubernetes API Endpoints in the Network Policy
kubernetes_api_ip = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].address[*].ip))
kubernetes_api_protocol = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].port[*].protocol))
kubernetes_api_port = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].port[*].port))
}

# Cloudnative PG Deployment for PostgreSQL Database Solution
module "cnpg" {
source = "git::https://github.com/necro-cloud/modules//modules/cnpg?ref=main"

// Garage Cluster Details for configuration of PITR Backups
garage_certificate_authority = module.garage.garage_internal_certificate_secret
garage_namespace = module.garage.garage_namespace
garage_configuration = "walbackups-credentials"
backup_bucket_name = "postgresql"

// Required client details to allow access and generate credentials and certificates for
clients = [
{
namespace = "cloud"
user = "cloud"
database = "cloud"
derRequired = false
privateKeyEncoding = "PKCS1"
}
]

// Certificate details for internal and ingress(pgadmin) certificates
cloudflare_token = var.cloudflare_token
cloudflare_email = var.cloudflare_email
domain = var.domain
cluster_issuer_name = module.cluster-issuer.cluster-issuer-name

// Whitelisting Kubernetes API Endpoints in the Network Policy
kubernetes_api_ip = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].address[*].ip))
kubernetes_api_protocol = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].port[*].protocol))
kubernetes_api_port = one(flatten(data.kubernetes_endpoints_v1.kubernetes_api_endpoint.subset[*].port[*].port))

// Dependency on Garage Deployment
depends_on = [module.garage]
}

# Keycloak Cluster Deployment for Identity Solution
module "keycloak" {
source = "git::https://github.com/necro-cloud/modules//modules/keycloak?ref=main"

// PostgreSQL Database Details for database details
cluster_issuer_name = module.cluster-issuer.cluster-issuer-name
postgres_namespace = module.cnpg.namespace
cluster_name = module.cnpg.cluster_name
database_server_certificate_authority_name = module.cnpg.server-certificate-authority
database_client_certificate_name = "postgresql-keycloak-client-certificate"
database_credentials = "credentials-keycloak"

// Certificate details for ingress
cloudflare_token = var.cloudflare_token
cloudflare_email = var.cloudflare_email
domain = var.domain

// Realm Settings for auto configuration of required clients
realm_settings = local.keycloak_realm_settings

// Dependency on CNPG PostgreSQL Deployment
depends_on = [module.cnpg]
}

# Valkey Deployment for In Memory Storage Solution
module "valkey" {
source = "git::https://github.com/necro-cloud/modules//modules/valkey?ref=main"

// Certificate details for TLS Authentication
cluster_issuer_name = module.cluster-issuer.cluster-issuer-name

// Granting required namespaces access to the Valkey
access_namespaces = "cloud"
}
29 changes: 29 additions & 0 deletions example/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.38.0"
}
helm = {
source = "hashicorp/helm"
version = "3.1.1"
}
random = {
source = "hashicorp/random"
version = "3.7.2"
}
}

backend "kubernetes" {
secret_suffix = "deployment"
}
}

provider "kubernetes" {
}

provider "helm" {
}

provider "random" {
}
133 changes: 133 additions & 0 deletions example/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# --------------- DNS SETTINGS VARIABLES --------------- #
variable "cloudflare_token" {
description = "Token for generating Ingress Certificates to be associated with MinIO Storage Solution"
type = string
nullable = false
}

variable "cloudflare_email" {
description = "Email for generating Ingress Certificates to be associated with MinIO Storage Solution"
type = string
nullable = false
}

variable "domain" {
description = "Domain for which Ingress Certificate is to be generated for"
type = string
nullable = false
}

# --------------- GARAGE CONFIGURATION VARIABLES --------------- #

variable "garage_required_access_keys" {
description = "Access Keys required to be configured within the Garage Cluster"
type = list(object({
name = string
createBucket = bool
permissions = list(object({
bucket = string
owner = bool
read = bool
write = bool
}))
}))
default = [
{
name = "walbackups",
createBucket = false,
permissions = [
{
bucket = "postgresql",
owner = true,
read = true,
write = true
}
]
},
{
name = "master",
createBucket = true,
permissions = [
{
bucket = "postgresql",
owner = true,
read = true,
write = true
},
{
bucket = "cloud",
owner = true,
read = true,
write = true
}]
},
{
name = "cloud",
createBucket = true,
permissions = [
{
bucket = "cloud",
owner = true,
read = true,
write = true
},
]
}]
}

variable "garage_required_buckets" {
description = "Buckets to deploy in the Garage Cluster"
type = list(string)
default = ["cloud", "postgresql"]
}

# --------------- KEYCLOAK REALM CONFIGURATION VARIABLES --------------- #

variable "keycloak_authentication_base_url" {
description = "Base URL for Keycloak in order to use SSO Authentication with"
type = string
default = "http://localhost:5173"
}

variable "keycloak_authentication_valid_login_redirect_path" {
description = "Valid Login Redirect Path for Keycloak in order to use SSO Authentication with"
type = string
default = "/auth/signin/callback"
}

variable "keycloak_authentication_valid_logout_redirect_path" {
description = "Valid Logout Redirect Path for Keycloak in order to use SSO Authentication with"
type = string
default = "/auth/signout/callback"
}

# --------------- SMTP SERVER VARIABLES --------------- #
variable "smtp_host" {
description = "Host of the SMTP Server to be used for sending mails"
type = string
nullable = false
}

variable "smtp_port" {
description = "Port Number of the SMTP Server to be used for sending mails"
type = number
nullable = false
}

variable "smtp_mail" {
description = "Mail ID of the SMTP Server to be used for sending mails"
type = string
nullable = false
}

variable "smtp_username" {
description = "Username of the SMTP Server to be used for authentication"
type = string
nullable = false
}

variable "smtp_password" {
description = "Password of the SMTP Server to be used for authentication"
type = string
nullable = false
}
2 changes: 1 addition & 1 deletion modules/cluster-issuer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Required Modules to deploy Cluster Issuer for internal certificates:

| Name | Version |
|------|---------|
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | 2.36.0 |
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | 2.38.0 |

## Resources

Expand Down
4 changes: 2 additions & 2 deletions modules/cnpg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Required Modules to deploy Cloudnative PG PostgreSQL Database:

| Name | Version |
|------|---------|
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | 2.36.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.7.1 |
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | 2.38.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.7.2 |

## Resources

Expand Down
4 changes: 2 additions & 2 deletions modules/garage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Required Modules to deploy Garage Object Storage:

| Name | Version |
|------|---------|
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | 2.36.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.7.1 |
| <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) | 2.38.0 |
| <a name="provider_random"></a> [random](#provider\_random) | 3.7.2 |

## Resources

Expand Down
2 changes: 1 addition & 1 deletion modules/helm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ OpenTofu Module to deploy the following required helm charts:

| Name | Version |
|------|---------|
| <a name="provider_helm"></a> [helm](#provider\_helm) | 3.0.0-pre2 |
| <a name="provider_helm"></a> [helm](#provider\_helm) | 3.1.1 |

## Resources

Expand Down
Loading