This commit is contained in:
Mike McFetridge
2026-07-20 09:23:17 -04:00
parent c1315882da
commit 72272e4006
3179 changed files with 562960 additions and 14 deletions
@@ -0,0 +1,15 @@
data "civo_ssh_key" "sshkey" {
name = "your-ssh-key-name"
}
resource "civo_instance" "server" {
hostname = "servername"
size = "g3.small"
disk_image = "ubuntu-focal"
# (optional):
# ---
# tags = ["python", "nginx"]
# notes = "this is a note for the server"
# initial_user = "user"
# sshkey_id = data.civo_ssh_key.sshkey.id
}
@@ -0,0 +1,9 @@
variable "zone_id" {}
resource "cloudflare_record" "server" {
zone_id = var.zone_id
name = "your-dns-name"
value = civo_instance.server.public_ip
type = "A"
proxied = false
}
@@ -0,0 +1,40 @@
# General Terraform Settings
# ---
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
civo = {
source = "civo/civo"
}
}
}
# Declare Variables
# ---
# TODO: Create a yourfile.auto.tfvars file in the project directory and add your variables in it.
# Example:
# cloudflare_email = "youremail@yourmail.com"
# cloudflare_api_key = "your-api-key"
# civo_token = "your-token"
variable "cloudflare_email" {}
variable "cloudflare_api_key" {}
variable "civo_token" {}
# Set Default Provider Settings
# ---
provider "cloudflare" {
email = var.cloudflare_email
api_key = var.cloudflare_api_key
}
provider "civo" {
token = var.civo_token
# (optional) change the defaullt region
# region = "FRA1"
}
@@ -0,0 +1,79 @@
resource "kubernetes_namespace" "certmanager" {
depends_on = [
time_sleep.wait_for_kubernetes
]
metadata {
name = "certmanager"
}
}
resource "helm_release" "certmanager" {
depends_on = [
kubernetes_namespace.certmanager
]
name = "certmanager"
namespace = "certmanager"
repository = "https://charts.jetstack.io"
chart = "cert-manager"
# Install Kubernetes CRDs
set {
name = "installCRDs"
value = "true"
}
}
resource "time_sleep" "wait_for_certmanager" {
depends_on = [
helm_release.certmanager
]
create_duration = "10s"
}
# Create a ClusterIssuer
resource "kubectl_manifest" "cloudflare_prod" {
depends_on = [
time_sleep.wait_for_certmanager
]
# TODO: add your mail address according to your configuration and API authentication settings!
# ---
yaml_body = <<YAML
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: cloudflare-prod
spec:
acme:
email: your-mail-address
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: cloudflare-prod-account-key
solvers:
- dns01:
cloudflare:
email: your-mail-address
apiKeySecretRef:
name: cloudflare-api-key-secret
key: api-key
YAML
}
resource "time_sleep" "wait_for_clusterissuer" {
depends_on = [
kubectl_manifest.cloudflare_prod
]
create_duration = "30s"
}
@@ -0,0 +1,77 @@
# Kubernetes Cluster
data "civo_size" "xsmall" {
# TODO: (optional): change the values according to your desired instance image sizing
# ---
filter {
key = "name"
values = ["g4s.kube.xsmall"]
match_by = "re"
}
}
resource "civo_kubernetes_cluster" "k8s_demo_1" {
name = "k8s_demo_1"
applications = ""
num_target_nodes = 2
target_nodes_size = element(data.civo_size.xsmall.sizes, 0).name
firewall_id = civo_firewall.fw_demo_1.id
}
resource "civo_firewall" "fw_demo_1" {
name = "fw_demo_1"
create_default_rules = false
}
resource "civo_firewall_rule" "kubernetes_http" {
firewall_id = civo_firewall.fw_demo_1.id
protocol = "tcp"
start_port = "80"
end_port = "80"
cidr = ["0.0.0.0/0"]
direction = "ingress"
action = "allow"
label = "kubernetes_http"
}
resource "civo_firewall_rule" "kubernetes_https" {
firewall_id = civo_firewall.fw_demo_1.id
protocol = "tcp"
start_port = "443"
end_port = "443"
cidr = ["0.0.0.0/0"]
direction = "ingress"
action = "allow"
label = "kubernetes_https"
}
resource "civo_firewall_rule" "kubernetes_api" {
firewall_id = civo_firewall.fw_demo_1.id
protocol = "tcp"
start_port = "6443"
end_port = "6443"
cidr = ["0.0.0.0/0"]
direction = "ingress"
action = "allow"
label = "kubernetes_api"
}
resource "time_sleep" "wait_for_kubernetes" {
depends_on = [
civo_kubernetes_cluster.k8s_demo_1
]
create_duration = "20s"
}
data "civo_loadbalancer" "traefik_lb" {
depends_on = [
helm_release.traefik
]
name = "k8s_demo_1-traefik-traefik"
}
@@ -0,0 +1,20 @@
# Cloudflare DNS records and API Secret
resource "kubernetes_secret" "cloudflare_api_key_secret" {
depends_on = [
kubernetes_namespace.certmanager
]
metadata {
name = "cloudflare-api-key-secret"
namespace = "certmanager"
}
data = {
api-key = var.cloudflare_api_key
}
type = "Opaque"
}
@@ -0,0 +1,153 @@
# NGINX 1 Test Deployment
#
# TODO: Change your-domain according to your DNS record that you want to create
# TODO: Change your-zone-id according to your DNS zone ID in Cloudflare
# ---
resource "kubernetes_namespace" "nginx1" {
depends_on = [
time_sleep.wait_for_kubernetes
]
metadata {
name = "nginx1"
}
}
resource "kubernetes_deployment" "nginx1" {
depends_on = [
kubernetes_namespace.nginx1
]
metadata {
name = "nginx1"
namespace = "nginx1"
labels = {
app = "nginx1"
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "nginx1"
}
}
template {
metadata {
labels = {
app = "nginx1"
}
}
spec {
container {
image = "nginx:latest"
name = "nginx"
port {
container_port = 80
}
}
}
}
}
}
resource "kubernetes_service" "nginx1" {
depends_on = [
kubernetes_namespace.nginx1
]
metadata {
name = "nginx1"
namespace = "nginx1"
}
spec {
selector = {
app = "nginx1"
}
port {
port = 80
}
type = "ClusterIP"
}
}
resource "kubectl_manifest" "nginx1-certificate" {
depends_on = [kubernetes_namespace.nginx1, time_sleep.wait_for_clusterissuer]
yaml_body = <<YAML
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: nginx1
namespace: nginx1
spec:
secretName: nginx1
issuerRef:
name: cloudflare-prod
kind: ClusterIssuer
dnsNames:
- 'your-domain'
YAML
}
resource "kubernetes_ingress_v1" "nginx1" {
depends_on = [kubernetes_namespace.nginx1]
metadata {
name = "nginx1"
namespace = "nginx1"
}
spec {
rule {
host = "your-domain"
http {
path {
path = "/"
backend {
service {
name = "nginx1"
port {
number = 80
}
}
}
}
}
}
tls {
secret_name = "nginx1"
hosts = ["your-domain"]
}
}
}
resource "cloudflare_record" "clcreative-main-cluster" {
zone_id = "your-zone-id"
name = "your-domain"
value = data.civo_loadbalancer.traefik_lb.public_ip
type = "A"
proxied = false
}
@@ -0,0 +1,76 @@
terraform {
required_version = ">= 0.13.0"
required_providers {
civo = {
source = "civo/civo"
version = "~> 1.0.13"
}
helm = {
source = "hashicorp/helm"
version = "2.14.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.31.0"
}
kubectl = {
source = "gavinbunney/kubectl"
version = "1.14.0"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
variable "civo_token" {
type = string
}
variable "cloudflare_email" {
type = string
}
variable "cloudflare_api_key" {
type = string
}
provider "civo" {
token = var.civo_token
# TODO: (optional) change region to your desired datacenter location
# ---
# region = "FRA1"
}
provider "helm" {
kubernetes {
host = "${yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).clusters.0.cluster.server}"
client_certificate = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).users.0.user.client-certificate-data)}"
client_key = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).users.0.user.client-key-data)}"
cluster_ca_certificate ="${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).clusters.0.cluster.certificate-authority-data)}"
}
}
provider "kubernetes" {
host = "${yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).clusters.0.cluster.server}"
client_certificate = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).users.0.user.client-certificate-data)}"
client_key = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).users.0.user.client-key-data)}"
cluster_ca_certificate = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).clusters.0.cluster.certificate-authority-data)}"
}
provider "kubectl" {
host = "${yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).clusters.0.cluster.server}"
client_certificate = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).users.0.user.client-certificate-data)}"
client_key = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).users.0.user.client-key-data)}"
cluster_ca_certificate = "${base64decode(yamldecode(civo_kubernetes_cluster.k8s_demo_1.kubeconfig).clusters.0.cluster.certificate-authority-data)}"
load_config_file = false
}
provider "cloudflare" {
email = var.cloudflare_email
api_key = var.cloudflare_api_key
}
@@ -0,0 +1,47 @@
# Traefik Deployment
resource "kubernetes_namespace" "traefik" {
depends_on = [
time_sleep.wait_for_kubernetes
]
metadata {
name = "traefik"
}
}
resource "helm_release" "traefik" {
depends_on = [
kubernetes_namespace.traefik
]
name = "traefik"
namespace = "traefik"
repository = "https://helm.traefik.io/traefik"
chart = "traefik"
# Set Traefik as the Default Ingress Controller
set {
name = "ingressClass.enabled"
value = "true"
}
set {
name = "ingressClass.isDefaultClass"
value = "true"
}
# Default Redirect
set {
name = "ports.web.redirectTo"
value = "websecure"
}
# Enable TLS on Websecure
set {
name = "ports.websecure.tls.enabled"
value = "true"
}
}
@@ -0,0 +1,24 @@
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.0"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:latest"
keep_locally = false
}
resource "docker_container" "nginx" {
image = docker_image.nginx.latest
name = "tutorial"
ports {
internal = 80
external = 8000
}
}