init exoscale cloud

This commit is contained in:
Serge Logvinov
2022-10-22 21:23:09 +03:00
parent 5e28e009f0
commit c5709dc867
16 changed files with 495 additions and 0 deletions

5
exoscale/auth.tf Normal file
View File

@@ -0,0 +1,5 @@
provider "exoscale" {
key = var.exoscale_api_key
secret = var.exoscale_api_secret
}

11
exoscale/common.tf Normal file
View File

@@ -0,0 +1,11 @@
data "exoscale_compute_template" "debian" {
for_each = { for idx, name in local.regions : name => idx }
zone = each.key
name = "Linux Debian 11 (Bullseye) 64-bit"
}
resource "exoscale_ssh_key" "terraform" {
name = "terraform"
public_key = file("~/.ssh/terraform.pub")
}

View File

@@ -0,0 +1,25 @@
resource "exoscale_anti_affinity_group" "controlplane" {
name = "${local.project}-controlplane"
description = "controlplane"
}
resource "exoscale_instance_pool" "controlplane" {
for_each = { for idx, name in local.regions : name => idx if try(var.controlplane[name].count, 0) > 0 }
zone = each.key
name = "controlplane-${each.key}"
instance_prefix = "controlplane-${each.key}"
size = var.controlplane[each.key].count
template_id = data.exoscale_compute_template.debian[each.key].id
ipv6 = true
security_group_ids = [local.network_secgroup[each.key].controlplane, local.network_secgroup[each.key].common]
network_ids = [local.network[each.key].id]
affinity_group_ids = [exoscale_anti_affinity_group.controlplane.id]
key_pair = exoscale_ssh_key.terraform.name
instance_type = try(var.controlplane[each.key].type, "standard.tiny")
disk_size = 10
labels = merge(var.tags, { type = "infra" })
}

25
exoscale/instances-web.tf Normal file
View File

@@ -0,0 +1,25 @@
resource "exoscale_anti_affinity_group" "web" {
name = "${local.project}-web"
description = "web"
}
resource "exoscale_instance_pool" "web" {
for_each = { for idx, name in local.regions : name => idx if try(var.instances[name].web_count, 0) > 0 }
zone = each.key
name = "web-${each.key}"
instance_prefix = "web"
size = var.instances[each.key].web_count
template_id = data.exoscale_compute_template.debian[each.key].id
ipv6 = true
security_group_ids = [local.network_secgroup[each.key].web, local.network_secgroup[each.key].common]
network_ids = [local.network[each.key].id]
affinity_group_ids = [exoscale_anti_affinity_group.web.id]
key_pair = exoscale_ssh_key.terraform.name
instance_type = try(var.instances[each.key].web_type, "standard.tiny")
disk_size = 10
labels = merge(var.tags, { type = "web" })
}

View File

@@ -0,0 +1,19 @@
resource "exoscale_instance_pool" "worker" {
for_each = { for idx, name in local.regions : name => idx if try(var.instances[name].worker_count, 0) > 0 }
zone = each.key
name = "worker-${each.key}"
instance_prefix = "worker"
size = var.instances[each.key].worker_count
template_id = data.exoscale_compute_template.debian[each.key].id
ipv6 = true
security_group_ids = [local.network_secgroup[each.key].common]
network_ids = [local.network[each.key].id]
key_pair = exoscale_ssh_key.terraform.name
instance_type = try(var.instances[each.key].worker_type, "standard.tiny")
disk_size = 10
labels = merge(var.tags, { type = "worker" })
}

75
exoscale/network-lb.tf Normal file
View File

@@ -0,0 +1,75 @@
resource "exoscale_nlb" "lb" {
for_each = { for idx, name in local.regions : name => idx if try(var.controlplane[name].count, 0) > 0 || try(var.instances[name].web_count, 0) > 0 }
zone = each.key
name = "lb-${each.key}"
labels = merge(var.tags, { type = "infra" })
}
resource "exoscale_nlb_service" "controlplane" {
for_each = { for idx, name in local.regions : name => idx if try(var.controlplane[name].count, 0) > 0 }
zone = each.key
name = "controlplane-${each.key}"
nlb_id = exoscale_nlb.lb[each.key].id
protocol = "tcp"
port = 6443
target_port = 6443
strategy = "round-robin"
healthcheck {
mode = "tcp"
port = 6443
interval = 15
timeout = 3
}
instance_pool_id = exoscale_instance_pool.controlplane[each.key].id
}
resource "exoscale_nlb_service" "http" {
for_each = { for idx, name in local.regions : name => idx if try(var.instances[name].web_count, 0) > 0 }
zone = each.key
name = "web-http-${each.key}"
nlb_id = exoscale_nlb.lb[each.key].id
protocol = "tcp"
port = 80
target_port = 80
strategy = "round-robin"
healthcheck {
mode = "http"
port = 80
interval = 15
timeout = 3
retries = 2
uri = "/"
}
instance_pool_id = exoscale_instance_pool.web[each.key].id
}
resource "exoscale_nlb_service" "https" {
for_each = { for idx, name in local.regions : name => idx if try(var.instances[name].web_count, 0) > 0 }
zone = each.key
name = "web-https-${each.key}"
nlb_id = exoscale_nlb.lb[each.key].id
protocol = "tcp"
port = 443
target_port = 443
strategy = "round-robin"
healthcheck {
mode = "https"
port = 443
interval = 15
timeout = 3
retries = 2
uri = "/"
}
instance_pool_id = exoscale_instance_pool.web[each.key].id
}

5
exoscale/prepare/auth.tf Normal file
View File

@@ -0,0 +1,5 @@
provider "exoscale" {
key = var.exoscale_api_key
secret = var.exoscale_api_secret
}

View File

@@ -0,0 +1,6 @@
data "exoscale_compute_template" "debian" {
for_each = { for idx, name in var.regions : name => idx }
zone = each.key
name = "Linux Debian 11 (Bullseye) 64-bit"
}

View File

@@ -0,0 +1,17 @@
resource "exoscale_compute_instance" "gw" {
for_each = { for idx, name in var.regions : name => idx if try(var.capabilities[name].network_gw_enable, false) }
zone = each.key
name = "${var.project}-${each.key}-gw"
template_id = data.exoscale_compute_template.debian[each.key].id
ipv6 = true
security_group_ids = [exoscale_security_group.gw.id, exoscale_security_group.common.id]
network_interface {
network_id = exoscale_private_network.main[each.key].id
ip_address = cidrhost("${exoscale_private_network.main[each.key].start_ip}/24", -3)
}
type = try(var.capabilities[each.key].network_gw_type, "standard.micro")
disk_size = 10
}

View File

@@ -0,0 +1,127 @@
resource "exoscale_security_group" "gw" {
name = "${var.project}-gw"
description = "gateway"
}
resource "exoscale_security_group_rule" "gw_ssh_v4" {
for_each = { for idx, ip in var.whitelist_admin : ip => idx }
security_group_id = exoscale_security_group.gw.id
description = "ssh"
type = "INGRESS"
protocol = "TCP"
cidr = each.key
start_port = 22
end_port = 22
}
resource "exoscale_security_group" "common" {
name = "${var.project}-common"
description = "common"
}
resource "exoscale_security_group_rule" "common_ssh_v4" {
security_group_id = exoscale_security_group.common.id
description = "ssh (IPv4)"
type = "INGRESS"
protocol = "TCP"
cidr = "0.0.0.0/0"
start_port = 22
end_port = 22
}
# resource "exoscale_security_group_rule" "common_localnet_tcp_v4" {
# security_group_id = exoscale_security_group.common.id
# description = "local network"
# type = "INGRESS"
# protocol = "TCP"
# cidr = var.network_cidr
# start_port = 1
# end_port = 65535
# }
# resource "exoscale_security_group_rule" "common_localnet_udp_v4" {
# security_group_id = exoscale_security_group.common.id
# description = "local network"
# type = "INGRESS"
# protocol = "UDP"
# cidr = var.network_cidr
# start_port = 1
# end_port = 65535
# }
resource "exoscale_security_group_rule" "common_talos_kubespan" {
for_each = { for idx, ip in ["0.0.0.0/0", "::/0"] : ip => idx }
security_group_id = exoscale_security_group.common.id
description = "talos kubespan"
type = "INGRESS"
protocol = "UDP"
cidr = each.key
start_port = 51820
end_port = 51820
}
resource "exoscale_security_group" "controlplane" {
name = "${var.project}-controlplane"
description = "controlplane"
}
resource "exoscale_security_group_rule" "controlplane_api" {
for_each = { for idx, ip in var.whitelist_admin : ip => idx }
security_group_id = exoscale_security_group.controlplane.id
description = "controlplane api"
type = "INGRESS"
protocol = "TCP"
cidr = each.key
start_port = 6443
end_port = 6443
}
resource "exoscale_security_group_rule" "controlplane_talos" {
for_each = { for idx, ip in var.whitelist_admin : ip => idx }
security_group_id = exoscale_security_group.controlplane.id
description = "talos"
type = "INGRESS"
protocol = "TCP"
cidr = each.key
start_port = 50000
end_port = 50001
}
resource "exoscale_security_group_rule" "controlplane_icmp" {
for_each = { for idx, ip in var.whitelist_admin : ip => idx if length(split(".", ip)) > 1 }
security_group_id = exoscale_security_group.controlplane.id
description = "ping"
type = "INGRESS"
protocol = "ICMP"
cidr = each.key
icmp_type = 8
icmp_code = 0
}
resource "exoscale_security_group" "web" {
name = "${var.project}-web"
description = "web"
}
resource "exoscale_security_group_rule" "web_http" {
for_each = { for idx, ip in var.whitelist_web : ip => idx }
security_group_id = exoscale_security_group.web.id
description = "http"
type = "INGRESS"
protocol = "TCP"
cidr = each.key
start_port = 80
end_port = 80
}
resource "exoscale_security_group_rule" "web_https" {
for_each = { for idx, ip in var.whitelist_web : ip => idx }
security_group_id = exoscale_security_group.web.id
description = "https"
type = "INGRESS"
protocol = "TCP"
cidr = each.key
start_port = 443
end_port = 443
}

View File

@@ -0,0 +1,10 @@
resource "exoscale_private_network" "main" {
for_each = { for idx, name in var.regions : name => idx }
zone = each.key
name = "${var.project}-${each.key}"
netmask = "255.255.255.0"
start_ip = cidrhost(cidrsubnet(var.network_cidr, 8, var.network_shift + each.value * 2), 60)
end_ip = cidrhost(cidrsubnet(var.network_cidr, 8, var.network_shift + each.value * 2), -6)
}

View File

@@ -0,0 +1,29 @@
output "project" {
description = "Exoscale project name"
value = var.project
}
output "regions" {
description = "Exoscale regions"
value = var.regions
}
output "network" {
description = "List of network"
value = { for zone, net in exoscale_private_network.main : zone => {
name = net.name
id = net.id
cidr = "${net.start_ip}/24"
gateway = cidrhost("${exoscale_private_network.main[zone].start_ip}/24", -3)
} }
}
output "secgroups" {
description = "List of secgroups"
value = { for zone, net in exoscale_private_network.main : zone => {
common = exoscale_security_group.common.id
controlplane = exoscale_security_group.controlplane.id
web = exoscale_security_group.web.id
} }
}

View File

@@ -0,0 +1,63 @@
variable "exoscale_api_key" { type = string }
variable "exoscale_api_secret" { type = string }
variable "project" {
type = string
default = "main"
}
variable "regions" {
description = "The region name list"
type = list(string)
default = ["de-fra-1", "de-muc-1"]
}
variable "tags" {
description = "Defined Tags of resources"
type = map(string)
default = {
"env" = "develop"
}
}
variable "network_name" {
type = string
default = "main"
}
variable "network_cidr" {
description = "Local subnet rfc1918/ULA"
type = string
default = "172.16.0.0/16"
}
variable "network_shift" {
description = "Network number shift"
type = number
default = 34
}
variable "whitelist_admin" {
default = ["0.0.0.0/0"]
}
variable "whitelist_web" {
default = ["0.0.0.0/0"]
}
variable "capabilities" {
type = map(any)
default = {
"de-fra-1" = {
network_lb = false,
network_gw_enable = false,
network_gw_type = "standard.micro",
},
"de-muc-1" = {
network_lb = false,
network_gw_enable = false,
network_gw_type = "standard.micro",
},
}
}

View File

@@ -0,0 +1,9 @@
terraform {
required_providers {
exoscale = {
source = "exoscale/exoscale"
version = "0.41.0"
}
}
}

60
exoscale/variables.tf Normal file
View File

@@ -0,0 +1,60 @@
variable "exoscale_api_key" { type = string }
variable "exoscale_api_secret" { type = string }
data "terraform_remote_state" "prepare" {
backend = "local"
config = {
path = "${path.module}/prepare/terraform.tfstate"
}
}
locals {
project = data.terraform_remote_state.prepare.outputs.project
regions = data.terraform_remote_state.prepare.outputs.regions
network = data.terraform_remote_state.prepare.outputs.network
network_secgroup = data.terraform_remote_state.prepare.outputs.secgroups
}
variable "tags" {
description = "Tags of resources"
type = map(string)
default = {
"env" = "develop"
}
}
variable "controlplane" {
description = "Controlplane config"
type = map(any)
default = {
"de-fra-1" = {
count = 0,
type = "standard.tiny",
},
"de-muc-1" = {
count = 0,
type = "standard.tiny",
},
}
}
variable "instances" {
description = "Map of region's properties"
type = map(any)
default = {
"de-fra-1" = {
web_count = 0,
web_type = "standard.tiny",
worker_count = 0,
worker_type = "standard.tiny",
},
"de-muc-1" = {
web_count = 0,
web_type = "standard.tiny",
worker_count = 0,
worker_type = "standard.tiny",
},
}
}

9
exoscale/versions.tf Normal file
View File

@@ -0,0 +1,9 @@
terraform {
required_providers {
exoscale = {
source = "exoscale/exoscale"
version = "0.41.0"
}
}
}