Add: Initial code

This commit is contained in:
jez 2022-03-21 23:27:54 -04:00
commit 335757bf44
37 changed files with 2020 additions and 0 deletions

81
cloud_project/main.tf Normal file
View File

@ -0,0 +1,81 @@
# Variables
# =====================
variable "cloud" {
description = "Cloud informations"
type = any
default = {}
}
variable "tenant" {
description = "Tenant informations"
type = any
default = {}
}
variable "deploy" {
description = "Deployment options"
type = any
default = {}
}
variable "stack" {
description = "Default stack"
type = any
default = {}
}
variable "stacks" {
description = "Deployments configuration"
type = any
default = []
}
# Resources
# =====================
locals {
# Fetch stack name
stack_name = try(
var.deploy.stack,
"main"
)
# Proceed to chained merges
stack = merge(
var.stack,
try(
var.stacks[local.stack_name], {}
)
)
}
module "virt_namespace" {
source = "../virt_namespace"
cloud = var.cloud
tenant = var.tenant
deploy = var.deploy
stack = local.stack
}
#module "iaas_inv_ansible" {
# source = "../iaas_inv_ansible"
# payload = var.config
#}
# Output
# =====================
output "namespace" {
value = module.virt_namespace
}
#output "iaas" {
# value = module.iaas_inv_ansible
#}

View File

View File

@ -0,0 +1,14 @@
---
terraform:
hosts:
mail.example.com:
children:
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:

View File

@ -0,0 +1,6 @@
${ ip_addrs }
%{ for addr in ip_addrs ~}
backend ${addr}:xx
%{ endfor ~}

View File

@ -0,0 +1,13 @@
variable "payload" {
description = "Payload informations"
type = any
default = {}
}
resource "local_file" "ansible_inventory" {
filename = "inventory.txt"
content = templatefile("${path.module}/inventory.tmpl", { ip_addrs = ["10.0.0.1", "10.0.0.2"] }
)
}
# tutu = ["bli", "blaaah"]
#toto = "${var.payload}"

View File

@ -0,0 +1,17 @@
[cfg]
%{ for index, group in ansible_group_cfg ~}
${ hostname_cfg[index] } ${ index == 0 ? "mongodb_primary=True" : "" }
%{ endfor ~}
%{ for shard_index in number_of_shards ~}
[shard${shard_index}]
%{ for index, group in ansible_group_shards ~}
${ group == tostring(shard_index) && ansible_group_index[index] == "0" ? join(" ", [ hostname_shards[index], "mongodb_primary=True\n" ]) : "" ~}
${ group == tostring(shard_index) && ansible_group_index[index] != "0" ? join("", [ hostname_shards[index], "\n" ]) : "" ~}
%{ endfor ~}
%{ endfor ~}
[mongos]
%{ for index, group in ansible_group_mongos ~}
${hostname_mongos[index]}
%{ endfor ~}

View File

@ -0,0 +1,42 @@
#variable "hostname" {
# description = "hostname"
# type = any
# default = {}
#}
#variable "groups" {
# description = "groups"
# type = any
# default = {}
#}
#variable "vars" {
# description = "Variables"
# type = any
# default = {}
#}
resource "ansible_host" "example2" {
inventory_hostname = "www.example.com"
groups = ["web"]
vars = {
foo = "bar"
}
}
resource "ansible_host" "example" {
inventory_hostname = "example.com"
groups = ["web"]
vars = {
ansible_user = "admin"
}
}
resource "ansible_group" "web" {
inventory_group_name = "web"
children = ["foo", "bar", "baz"]
vars = {
foo = "bar"
bar = 2
}
}

View File

@ -0,0 +1,9 @@
terraform {
required_providers {
ansible = {
source = "nbering/ansible"
version = "1.0.4"
}
}
}

34
iaas_inv_ansible/main.tf Normal file
View File

@ -0,0 +1,34 @@
variable "payload" {
description = "Instance description"
type = any
default = {}
}
resource "ansible_host" "example2" {
inventory_hostname = "www.example.com"
groups = ["web"]
vars = {
foo = "bar"
}
}
resource "ansible_host" "example" {
inventory_hostname = "example.com"
groups = ["web"]
vars = {
ansible_user = "admin"
}
}
resource "ansible_group" "web" {
inventory_group_name = "web"
children = ["foo", "bar", "baz"]
vars = {
foo = "bar"
bar = 2
}
}

View File

89
virt_cloudinit/main.tf Normal file
View File

@ -0,0 +1,89 @@
# Variables
# ============
variable "name" {
type = string
}
variable "pool" {
type = string
default = "default"
}
variable "userdata" {
type = string
default = ""
}
# Main
# ============
# Cloud init ISO
resource "libvirt_cloudinit_disk" "volume_cloudinit" {
name = var.name
pool = var.pool
user_data = var.userdata
}
# Outputs
# ============
output "volume" {
value = libvirt_cloudinit_disk.volume_cloudinit
}
# ==================== DEPRECATED !!!!
# variable "baked_image" {
# type = bool
# default = true
# }
#
# variable "image_name" {
# type = string
# }
#
# variable "image_pool" {
# type = string
# }
# variable "image_dir" {
# type = string
# }
# variable "image_url" {
# type = string
# }
# Deprecated by cloud_volume !
# # Baked volume
# resource "libvirt_volume" "volume_system_baked" {
# name = "${var.prefix}system.qcow2"
# count = var.baked_image ? 1 : 0
# pool = var.pool
#
# base_volume_name = var.image_name
# base_volume_pool = var.image_pool
# size = var.disk_size_gb * 1024 * 1024 * 1024
# }
#
# # Copied volume
# resource "libvirt_volume" "volume_system_full" {
# name = "${var.prefix}system.qcow2"
# count = var.baked_image ? 0 : 1
# pool = var.pool
#
# #source = var.baked_image ? "" : "${var.image_dir}/${var.image_name}"
# source = var.image_url
# }
#
#output "volume_os" {
# value = var.baked_image ? resource.libvirt_volume.volume_system_baked[0] : resource.libvirt_volume.volume_system_full[0]
#}

View File

@ -0,0 +1,8 @@
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.14"
}
}
}

93
virt_flavor/main.tf Normal file
View File

@ -0,0 +1,93 @@
# Flavors
# ========================
variable "flavor" {
description = "The flavor to use"
type = string
default = "small"
}
# Default flavors
locals {
flavors = {
"default" = {
"cpu" = 2,
"ram" = 1024,
"disk" = 5
},
"tiny" = {
"cpu" = 1,
"ram" = 512,
"disk" = 5
},
"tiny_ram" = {
"cpu" = 1,
"ram" = 1024,
"disk" = 10
},
"small" = {
"cpu" = 2,
"ram" = 2048,
"disk" = 10
},
"small_ram" = {
"cpu" = 2,
"ram" = 4096,
"disk" = 10
},
"medium" = {
"cpu" = 4,
"ram" = 4096,
"disk" = 10
},
"medium_ram" = {
"cpu" = 4,
"ram" = 6144,
"disk" = 10
},
"large" = {
"cpu" = 6,
"ram" = 6144,
"disk" = 20
},
"large_ram" = {
"cpu" = 6,
"ram" = 8192,
"disk" = 10
},
"huge" = {
"cpu" = 8,
"ram" = 8192,
"disk" = 10
},
"huge_ram" = {
"cpu" = 8,
"ram" = 12288,
"disk" = 10
}
}
}
locals {
flavor = local.flavors[var.flavor]
cpu = local.flavor.cpu
ram = local.flavor.ram
disk = local.flavor.disk
}
output "flavor" {
value = local.flavor
}
output "cpu" {
value = local.cpu
}
output "disk" {
value = local.disk
}
output "ram" {
value = local.ram
}

0
virt_flavor/provider.tf Normal file
View File

54
virt_images/main.tf Normal file
View File

@ -0,0 +1,54 @@
# Variables
# =====================
variable "images" {
description = "Images definitions"
type = any
default = {}
}
variable "images_defaults" {
description = "Images default definitions"
type = map
default = {
pool = "default",
}
}
# Resources
# =====================
locals {
images = flatten(
[for dist_name, dist_config in var.images:
{
name = dist_name
format = try(dist_config.format, "")
file = try(dist_config.file, "${dist_name}.${dist_config.format}" , basename( dist_config.url ))
url = dist_config.url
pool = try(dist_config.pool, var.images_defaults.pool, "default")
}
]
)
}
module "volumes" {
source = "../virt_volumes"
volumes = local.images
volumes_defaults = var.images_defaults
}
# Outputs
# =====================
output "images" {
value = local.images
}
output "volumes" {
value = module.volumes.volumes
}

0
virt_images/provider.tf Normal file
View File

362
virt_instance/main.tf Normal file
View File

@ -0,0 +1,362 @@
# See:
# https://github.com/sk4zuzu/vm-pool/blob/master/terraform/redhat/nodes/domain.tf
# SEE: https://github.com/SUSE/ha-sap-terraform-deployments/blob/master/libvirt/modules/hana_node/main.tf#L21
#variable "tenant_networks" {
# type = any
# default = {}
#}
# Variables
# =====================
variable "name" {
description = "Instance name"
type = string
}
variable "domain" {
description = "Instance domain"
type = string
default = ""
}
variable "number" {
description = "Number of instances"
type = number
default = 1
}
#
variable "prefix" {
description = "String to prefix each instances"
type = string
default = ""
}
variable "name_fqdn" {
description = "Define instance name with fqdn"
type = bool
default = false
}
variable "name_prefix" {
description = "Define instance name with project prefix"
type = bool
default = true
}
variable "instance_pool" {
description = "Volume pool for instance disks"
type = string
default = "default"
}
variable "images_pool" {
description = "Default image pool"
type = string
default = "default"
}
variable "disk_gb" {
description = "Size in gb of the root disk"
type = number
default = 2
}
#
variable "flavor" {
description = "Instance flavor"
type = string
default = "x-small"
}
variable "memory" {
description = "Instance memory"
type = string
default = "2048"
}
variable "vcpu" {
description = "Number of vcpu"
type = number
default = 2
}
variable "disks" {
description = "Ephemeral disks list"
type = list
default = []
}
variable "volumes" {
description = "Persistant volume list"
type = list
default = []
}
variable "networks" {
description = "Network list"
type = list
default = []
}
variable "wait_for_lease" {
description = "Wait for network ip assignment"
type = bool
default = false
}
variable "metadata" {
description = "Metadata do add in state"
type = any
default = {}
}
# Cloud init
# -----------
variable "user" {
description = "Default user login"
type = string
default = "cloud"
}
variable "authorized_key" {
description = "Default user authorized key"
type = string
default = ""
}
# Note: This should only be used for debugging purpose
variable "password_hash" {
description = "Default user password hash (ie: $1$SaltSalt$GhE887kYCerthShgxern00)"
type = string
default = ""
# sensitive = true
}
# Cloud settings
# =====================
module "system_os" {
source = "../../modules/virt_os"
count = var.number
os_name = "debian"
os_version = "10"
domain = var.domain
hostname = "${var.name}${count.index}"
user = var.user
password_hash = var.password_hash
authorized_key = var.authorized_key
}
module "system_flavor" {
source = "../../modules/virt_flavor"
count = var.number
flavor = var.flavor
}
# Volumes Configuration
# =====================
module "volume_cloudinit" {
source = "../virt_cloudinit"
count = var.number
name = "inst_${var.prefix}${var.name}${count.index}_cloudinit.iso"
pool = var.instance_pool
userdata = module.system_os[count.index].template
}
module "volume_os" {
source = "../virt_volume"
count = var.number
format = "qcow2"
name = "inst_${var.prefix}${var.name}${count.index}"
pool = var.instance_pool
size_gb = 42
base_pool = var.images_pool
# TOFIX: Hardcoded refrence to debian
base_file = "debian_latest.qcow2"
}
module "volumes_extra" {
source = "../virt_volumes"
count = var.number
volumes = var.disks
volumes_defaults = {
prefix = "inst_${var.prefix}${var.name}${count.index}_"
pool = var.instance_pool
# TOFIX: Hardcoded variable
pool_dir = "/virt"
}
}
# Instance
# =====================
locals {
hostname = replace( var.name, "_", "-")
vmname = ( var.name_prefix ?
"${var.prefix}${local.hostname}":
"${local.hostname}" )
domain = var.domain
metadata = {
#cloud_init = one(module.system_os[*].template)
os_name = "debian"
os_version = "10"
domain = var.domain
user = var.user
#password_hash = var.password_hash
authorized_key = var.authorized_key
}
}
resource "ansible_host" "ansible_def" {
count = var.number
inventory_hostname = ( var.name_fqdn ?
"${local.hostname}${count.index}.${var.domain}" :
"${local.hostname}${count.index}" )
#groups = [
# "role_${local.hostname}",
# var.prefix != "" ? "prj_${var.prefix}" : ""
# ]
vars = {
ansible_user = var.user
ansible_host = "${local.hostname}${count.index}.${var.domain}"
ansible_connection = "ssh"
instances_count = var.number
instances_index = count.index
instance_domain = var.domain
instance_hostname = "${local.hostname}${count.index}"
instance_name = "${local.hostname}"
instance_provisionning_key = var.authorized_key
instance_provisionning_user = var.user
instance_flavor = var.flavor
instance_metadata = jsonencode(merge(local.metadata, var.metadata))
# TOFIX: lol
instance_os_name = "debian"
instance_os_version = "10"
instance_vm = ( var.name_fqdn ?
"${local.vmname}${count.index}.${var.domain}" :
"${local.vmname}${count.index}" )
}
}
resource "libvirt_domain" "instdef" {
count = var.number
autostart = true
name = ( var.name_fqdn ?
"${local.vmname}${count.index}.${var.domain}" :
"${local.vmname}${count.index}" )
description = "${var.name}${count.index}.${var.domain}"
memory = var.memory
vcpu = var.vcpu
metadata = jsonencode(merge(local.metadata, var.metadata))
# Root FS
# -------------------
cloudinit = module.volume_cloudinit[count.index].volume.id
disk {
volume_id = module.volume_os[count.index].volume.id
}
# Instance disks
dynamic "disk" {
for_each = module.volumes_extra[count.index].volumes
content {
volume_id = disk.value.volume.id
#volume_id = disk.value.info.id
#volume_id = coalesce(disk.value.volume.id)
#file = coalesce(disk.value.info.id)
}
}
# Networking
# -------------------
dynamic "network_interface" {
for_each = var.networks
content {
network_name = network_interface.value.name
mac = try(network_interface.value.mac, null)
addresses = try(network_interface.value.addresses, null)
#hostname = try(network_interface.value.hostname, var.name)
wait_for_lease = try(network_interface.value.wait_for_lease, var.wait_for_lease )
macvtap = try(network_interface.value.macvtap, null)
vepa = try(network_interface.value.vepa, null)
}
}
# Other
# -------------------
console {
type = "pty"
target_port = "0"
target_type = "serial"
}
console {
type = "pty"
target_type = "virtio"
target_port = "1"
}
graphics {
type = "spice"
listen_type = "address"
autoport = true
}
cpu {
mode = "host-passthrough"
}
}
# Outputs
# =====================
output "instance" {
value = try(resource.libvirt_domain.instdef, null)
}
# output "volume_cloudinit" {
# value = module.volume_cloudinit
# }
output "volume_os" {
value = module.volume_os
}
output "volumes_extra" {
value = module.volumes_extra
}
# Tag infos
output "system_os" {
value = module.system_os
}
output "system_flavor" {
value = module.system_flavor
}

12
virt_instance/provider.tf Normal file
View File

@ -0,0 +1,12 @@
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.14"
}
ansible = {
source = "nbering/ansible"
version = "~>1.0.4"
}
}
}

112
virt_instances/main.tf Normal file
View File

@ -0,0 +1,112 @@
# Variables
# =====================
variable "tenant" {
description = "Tenant informations"
type = any
default = {
prefix = ""
}
}
variable "instances" {
description = "Instances definitions"
type = any
default = []
}
variable "instances_defaults" {
description = "Instances default definitions"
type = any
default = {}
}
variable "networks" {
description = "Known networks to find domain"
type = any
default = {}
}
# Resources
# =====================
locals {
pre_default = {
network = "default"
domain = "no_domain22"
}
default_network = try(var.networks[var.instances_defaults.default_network], null) != null ? var.instances_defaults.default_network : local.pre_default.network
networks = local.default_network != null ? [{ name = "${var.tenant.prefix}${local.default_network}" }] : []
domain = try( var.networks[local.default_network].domain, local.pre_default.domain)
# Recommended default flavor
default = {
number = 1
instance_pool = "default"
disk_gb = 14
flavor = "default"
memory = 1024
vcpu = 1
disks = []
volumes = []
name_fqdn = true
wait_for_lease = false
password_hash = ""
authorized_key = ""
user = ""
metadata = {}
prefix = var.tenant.prefix
default_network = local.default_network
networks = local.networks
domain = local.domain
}
instances_defaults = merge(local.default, var.instances_defaults)
}
module "virt_instances" {
source = "../../modules/virt_instance"
for_each = { for v in var.instances : v.name => merge(local.instances_defaults, v) }
name = each.value.name
prefix = each.value.prefix
name_fqdn = each.value.name_fqdn
metadata = each.value.metadata
domain = each.value.domain
number = each.value.number
instance_pool = each.value.instance_pool
images_pool = each.value.images_pool
disk_gb = each.value.disk_gb
flavor = each.value.flavor
memory = each.value.memory
vcpu = each.value.vcpu
disks = each.value.disks
volumes = each.value.volumes
networks = each.value.networks
wait_for_lease = each.value.wait_for_lease
user = each.value.user
authorized_key = each.value.authorized_key
password_hash = each.value.password_hash
}
# Outputs
# =====================
output "instances" {
value = module.virt_instances
}
# output "DEBUG" {
# value = {
# NORMAL = module.virt_instances
# INSTANCES = var.instances
# INSTANCES_defaults = var.instances_defaults
# }
# }

View File

147
virt_namespace/main.tf Normal file
View File

@ -0,0 +1,147 @@
# Variables
# =====================
variable "cloud" {
description = "Cloud informations"
type = any
default = {}
}
variable "tenant" {
description = "Tenant informations"
type = any
default = {}
}
variable "deploy" {
description = "Deployments configuration"
type = map
default = {}
}
variable "stack" {
description = "Deployment options"
type = any
default = {}
}
# Resources
# =====================
locals {
def_deploy = {
stack = "main"
pools = false
volumes = false
networks = false
instances = false
images = false
}
base_stack = {
pool = {}
image = {}
volume = {}
network = {}
instance = {}
pools = {}
images = {}
volumes = []
networks = {}
instances = []
}
deploy = merge ( local.def_deploy, var.deploy )
stack = { for k, v in local.base_stack:
k => try(
merge (
local.base_stack[k],
var.cloud[k],
var.stack[k]
),
var.stack[k],
var.cloud[k]
,local.base_stack[k]
)
}
}
# Modules
# =====================
module "cloud_pools" {
source = "../virt_pools"
count = local.deploy.pools ? 1: 0
pools = local.stack.pools
pools_defaults = local.stack.pool
}
module "cloud_images" {
source = "../virt_images"
count = local.deploy.images ? 1: 0
depends_on = [module.cloud_pools]
images = local.stack.images
images_defaults = local.stack.image
}
module "cloud_volumes" {
source = "../virt_volumes"
count = local.deploy.volumes ? 1: 0
depends_on = [module.cloud_pools]
tenant = var.tenant
volumes = local.stack.volumes
volumes_defaults = local.stack.volume
}
module "cloud_networks" {
source = "../virt_networks"
count = local.deploy.networks ? 1: 0
tenant = var.tenant
networks = local.stack.networks
networks_defaults = local.stack.network
}
module "cloud_instances" {
source = "../virt_instances"
count = local.deploy.instances ? 1: 0
depends_on = [module.cloud_networks, module.cloud_images, module.cloud_volumes]
tenant = var.tenant
networks = local.stack.networks
instances = local.stack.instances
instances_defaults = local.stack.instance
}
# Output
# =====================
output "cloud_pools" {
value = module.cloud_pools
}
output "cloud_images" {
value = module.cloud_images
}
output "cloud_volumes" {
value = module.cloud_volumes
}
output "cloud_networks" {
value = module.cloud_networks
}
output "cloud_instances" {
value = module.cloud_instances
}
# output "DEBUG" {
# value = local.stack
# }

View File

171
virt_network/main.tf Normal file
View File

@ -0,0 +1,171 @@
# Variables
# =====================
variable "name" {
type = string
description = "Network name"
}
variable "mode" {
description = "Network mode (route|nat)"
type = string
default = "nat"
}
variable "bridge" {
description = "Network interface name (16 char max, virbr_)"
type = string
}
variable "domain" {
description = "Network domain"
type = string
default = "local"
}
variable "gw4" {
description = "Network address"
type = string
default = "192.168.0.1"
}
variable "mask" {
description = "Netmask of the network"
type = number
default = 24
}
#
variable "nat_enable" {
description = "Enable NAT from outside of libvirt"
type = bool
default = false
}
variable "nat_driver" {
description = "Default NAT driver"
type = string
default = "ferm"
}
variable "nat_device" {
description = "Device to forward unrouted traffic (ie: eth0)"
type = string
default = "enp1s0"
}
#
variable "vip" {
description = "List of vips"
type = list
default = []
}
variable "subnets" {
description = "List of subnets"
type = list
default = []
}
# Resources
# =====================
resource "libvirt_network" "netdef" {
name = var.name
mode = var.mode
bridge = var.bridge
domain = var.domain
addresses = ["${var.gw4}/${var.mask}"]
autostart = true
dns {
enabled = true
local_only = true
hosts {
hostname = "gw"
ip = cidrhost("${var.gw4}/${var.mask}", 1)
}
dynamic "hosts" {
for_each = var.vip
content {
hostname = try(hosts.value.hostname)
ip = try(hosts.value.ip)
}
}
}
}
# Tests
# =====================
# resource "consul_keys" "app" {
# count = var.nat_enable ? 1 : 0
#
# depends_on = [libvirt_network.netdef]
# key {
# path = "tests/net/${var.bridge}/nat"
# value = "${var.nat_device} - ${ var.nat_enable }"
# delete = true
# }
# }
# TMP DISABVLED, require ferm first resource "ssh_resource" "nat_config" {
# TMP DISABVLED, require ferm first count = var.nat_enable ? 1 : 0
# TMP DISABVLED, require ferm first
# TMP DISABVLED, require ferm first host = "192.168.142.10"
# TMP DISABVLED, require ferm first user = "root"
# TMP DISABVLED, require ferm first agent = true
# TMP DISABVLED, require ferm first
# TMP DISABVLED, require ferm first depends_on = [libvirt_network.netdef]
# TMP DISABVLED, require ferm first
# TMP DISABVLED, require ferm first file {
# TMP DISABVLED, require ferm first content = templatefile("${path.module}/templates/ferm_nat.tpl", {
# TMP DISABVLED, require ferm first device = "${var.nat_device}"
# TMP DISABVLED, require ferm first driver = "${var.nat_driver}"
# TMP DISABVLED, require ferm first })
# TMP DISABVLED, require ferm first destination = "/etc/libvirt/hooks/state/net/${var.bridge}_nat.ini"
# TMP DISABVLED, require ferm first permissions = "0644"
# TMP DISABVLED, require ferm first }
# TMP DISABVLED, require ferm first }
# resource "ssh_resource" "ipvs_config" {
# count = var.nat_enable ? 1 : 0
#
# host = "192.168.142.10"
# user = "root"
# agent = true
#
# depends_on = [libvirt_network.netdef]
#
# file {
# content = templatefile("${path.module}/templates/ipvs_config.tpl", {
# vips = var.vip
# })
# destination = "/etc/libvirt/hooks/state/net/${var.bridge}_ipvs.ini"
# permissions = "0644"
# }
# }
# Output
# =====================
output "networks" {
value = resource.libvirt_network.netdef
}
output "subnets" {
value = var.subnets
}
output "vips" {
value = var.vip
}

12
virt_network/provider.tf Normal file
View File

@ -0,0 +1,12 @@
terraform {
required_providers {
libvirt = {
source = "registry.terraform.io/dmacvicar/libvirt"
version = "0.6.14"
}
# ssh = {
# source = "registry.terraform.io/loafoe/ssh"
# version = "0.4.0"
# }
}
}

View File

@ -0,0 +1,3 @@
[nat]
driver = ${ driver }
device = ${ device }

View File

@ -0,0 +1,8 @@
[ipvs]
%{ for vip in vips }
%{ if can(vip.public_ip) && can(vip.public_port) }
-A -t ${vip.public_ip}:${vip.public_port} -s rr
-a -t ${vip.public_ip}:${vip.public_port} -r ${vip.ip}:${try(vip.internal_port, vip.public_port)} -m -w 1
%{ endif }
%{ endfor }

73
virt_networks/main.tf Normal file
View File

@ -0,0 +1,73 @@
# Variables
# =====================
variable "tenant" {
description = "Tenant informations"
type = any
default = {
prefix = ""
}
}
variable "networks" {
description = "Networks definitions"
type = any
default = {}
}
variable "networks_defaults" {
description = "Network default definitions"
type = any
default = {}
}
# Resources
# =====================
locals {
defaults = {
name_prefix = var.tenant.prefix
#interface_prefix = "vibr_${var.tenant.prefix}"
#interface_prefix = "vibr_"
interface_prefix = null
mode = "nat"
domain = "local"
gw4 = "192.168.100.1"
mask = "24"
nat_enable = false
vip = []
subnets = []
}
networks_defaults = merge(local.defaults, var.networks_defaults)
}
module "cloud_networks" {
source = "../../modules/virt_network"
for_each = { for k, v in var.networks : k => merge(local.networks_defaults, v) }
name = "${each.value.name_prefix}${each.key}"
bridge = each.value.interface_prefix == null ? "" : substr("${each.value.interface_prefix}${each.key}", 0 , 15)
mode = each.value.mode
domain = each.value.domain
gw4 = each.value.gw4
mask = each.value.mask
nat_enable = each.value.nat_enable
vip = each.value.vip
subnets = each.value.subnets
}
# Output
# =====================
output "networks" {
value = module.cloud_networks
}

View File

194
virt_os/main.tf Normal file
View File

@ -0,0 +1,194 @@
# Instance System
# ========================
# Variables
variable "os_name" {
description = "The name of the operating system to create"
type = string
default = "ubuntu"
}
variable "os_version" {
description = "The version of the operationg system to use"
type = string
default = "latest"
}
# ========
variable "cloud_init" {
type = string
default = ""
description = "Override system cloud_init"
}
variable "cloud_init_vars" {
type = map
default = {}
description = "Override cloud init vars"
}
# ==========
variable "domain" {
type = string
default = "nodomain"
}
variable "hostname" {
type = string
default = "noname"
}
variable "user" {
type = string
default = "cloud"
}
variable "password_hash" {
type = string
default = ""
}
variable "authorized_key" {
type = string
default = ""
}
locals {
# Operating System
# ========================
distro = {
"debian" = {
"latest" = {
"cloud_init" = "debian",
"url" = "https://cdimage.debian.org/cdimage/cloud/buster/20210208-542/debian-10-genericcloud-amd64-20210208-542.qcow2",
},
"10" = {
"cloud_init" = "debian",
"url" = "https://cdimage.debian.org/cdimage/cloud/buster/20210208-542/debian-10-genericcloud-amd64-20210208-542.qcow2",
},
"10-20210208-542" = {
"cloud_init" = "debian",
"url" = "https://cdimage.debian.org/cdimage/cloud/buster/20210208-542/debian-10-genericcloud-amd64-20210208-542.qcow2",
},
},
# "ubuntu" = {
# "latest" = {
# "cloud_init" = "debian",
# "url" = "https://cloud-images.ubuntu.com/releases/groovy/release/ubuntu-20.10-server-cloudimg-amd64-disk-kvm.img",
# },
# "20.10" = {
# "cloud_init" = "debian",
# "url" = "https://cloud-images.ubuntu.com/releases/groovy/release/ubuntu-20.10-server-cloudimg-amd64-disk-kvm.img",
# },
# "20.04" = {
# "cloud_init" = "debian",
# "url" = "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img",
# },
# "19.04" = {
# "cloud_init" = "debian",
# "url" = "https://cloud-images.ubuntu.com/releases/disco/release/ubuntu-19.04-server-cloudimg-amd64.img",
# },
# "18.04" = {
# "cloud_init" = "debian",
# "url" = "https://cloud-images.ubuntu.com/releases/bionic/release/ubuntu-18.04-server-cloudimg-amd64.img",
# },
# "17.04" = {
# "cloud_init" = "debian",
# "url" = "http://cloud-images-archive.ubuntu.com/releases/zesty/release-20171208/ubuntu-17.04-server-cloudimg-amd64.img",
# },
# "16.04" = {
# "cloud_init" = "debian",
# "url" = "https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img"
# },
# },
# "centos" = {
# "latest" = {
# "cloud_init" = "centos",
# "url" = "https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.3.2011-20201204.2.x86_64.qcow2",
# },
# "8" = {
# "cloud_init" = "centos",
# "url" = "https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.3.2011-20201204.2.x86_64.qcow2",
# },
# "8-stream" = {
# "cloud_init" = "centos",
# "url" = "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20201217.0.x86_64.qcow2",
# },
# "7" = {
# "cloud_init" = "centos",
# "url" = "https://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-2009.qcow2",
# },
# "6" = {
# "cloud_init" = "centos",
# "url" = "https://cloud.centos.org/centos/6/images/CentOS-6-x86_64-GenericCloud.qcow2"
# },
# }
}
# Cloud Init
# ========================
templates = {
"centos" = {
"template" = "${path.module}/templates/cloud_centos_generic.yml",
"vars" = {}
},
"debian" = {
"template" = "${path.module}/templates/cloud_debian_generic.yml",
"vars" = {
"authorized_key" = "",
"authorized_keys" = [],
"commands" = [],
"packages" = [],
"allow_passwords" = true,
}
}
}
template_default = {
"authorized_key" = var.authorized_key,
"password_hash" = var.password_hash,
"user" = var.user,
"domain" = var.domain,
"hostname" = var.hostname,
}
}
locals {
os = local.distro[var.os_name][var.os_version]
# Generate template
cloud_template = try(local.templates[var.cloud_init], local.templates[local.os.cloud_init])
template_vars = merge(local.cloud_template.vars, local.template_default, var.cloud_init_vars)
}
output "distro" {
value = local.distro
}
output "os" {
value = local.os
}
output "cloud_init" {
value = local.cloud_template
}
output "template_vars" {
value = local.template_vars
}
output "template" {
#value = data.template_file.user_data.rendered
value = templatefile("${local.cloud_template.template}", local.template_vars)
}

0
virt_os/provider.tf Normal file
View File

View File

@ -0,0 +1,57 @@
#cloud-config
preserve_hostname: false
hostname: ${hostname}
fqdn: ${hostname}.${domain}
# prefer_fqdn_over_hostname: true
%{ if allow_passwords ~}
ssh_pwauth: true
%{ endif ~}
groups:
- wheel
users:
- name: ${user}
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users, admin, sudo
%{ if allow_passwords ~}
passwd: "${password_hash}"
%{ endif ~}
lock_passwd: %{ if allow_passwords ~}false%{ else }true%{ endif }
ssh_authorized_keys:
%{ if authorized_key != "" ~}
- "${authorized_key}"
%{ endif ~}
%{ for key in authorized_keys ~}
- "${key}"
%{ endfor ~}
packages:
- vim
- telnet
- bash-completion
- htop
- tree
- lvm2
%{ for pkg in packages ~}
- ${pkg}
%{ endfor ~}
bootcmd:
- echo "127.0.0.1 ${hostname}.${domain} ${hostname}" >> /etc/hosts
runcmd:
- rm /etc/skel/.bashrc
- apt update
- apt install -y qemu-guest-agent ca-certificates
- systemctl enable qemu-guest-agent
- systemctl start qemu-guest-agent
- apt upgrade
%{ for cmd in commands ~}
- ${cmd}
%{ endfor ~}
- echo "$(date): Success" > /var/log/provisionned
final_message: "The system is ready, after $UPTIME seconds"

55
virt_pools/main.tf Normal file
View File

@ -0,0 +1,55 @@
# Variables
# =====================
variable "tenant" {
description = "Tenant informations"
type = any
default = {
prefix = ""
}
}
variable "pools" {
description = "Pools definitions"
type = any
default = {}
}
variable "pools_defaults" {
description = "Pools default definitions"
type = any
default = {}
}
locals {
defaults = {
root_dir = "/virt"
}
pools_defaults = merge(local.defaults, var.pools_defaults)
}
# Resources
# =====================
resource "libvirt_pool" "pooldef" {
for_each = var.pools
name = "${each.key}"
path = length(
regexall("^/", try( each.value.dir, ""))
) > 0 ? "${each.value.dir}" : "${local.pools_defaults.root_dir}/${try( each.value.dir, each.key)}"
type = "dir"
}
# Output
# =====================
output "pools" {
value = resource.libvirt_pool.pooldef
}

8
virt_pools/provider.tf Normal file
View File

@ -0,0 +1,8 @@
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.14"
}
}
}

262
virt_volume/main.tf Normal file
View File

@ -0,0 +1,262 @@
# Variables
# =====================
#
variable "name" {
type = string
description = "Determine the name of the volume"
}
variable "persistant" {
type = bool
default = false
description = "Enable destroy protection on this volume"
}
#
variable "format" {
type = string
default = "qcow2"
description = "Determine the format of the image"
}
variable "file" {
type = string
description = "Determine the filename of the volume"
default = ""
}
#
variable "pool" {
type = string
default = "default"
description = "Determine pool to create volume within"
}
variable "pool_dir" {
type = string
default = "/virt"
description = "Default path for all pools"
}
variable "size_gb" {
type = number
default = 0
description = "Default size for the volume"
}
#
variable "url" {
type = string
default = ""
description = "Download url for volume"
}
variable "base_pool" {
type = string
default = "default"
description = "Pool of the source image"
}
variable "base_file" {
type = string
description = "Name of the source image"
default = ""
}
# Variables
# =====================
#agent=var.ssh_agent # "true"
#host=var.ssh_host # "wks1.office.barbu-it.net"
#user=var.ssh_user # "root"
#password=var.password
variable "ssh_conn" {
description = "Default settings for ssh connexion"
type = any
default = {
agent = true,
#host = "localhost",
host = "wks1.office.barbu-it.net",
user = null,
password = null
}
}
# Resources
# =====================
locals {
# Guess things from URL
url_split = split(".", basename( var.url ))
url_ext = element(local.url_split, length(local.url_split ) -1 )
url_file = "${var.name}.${local.url_ext}"
# Guess things from name
name_file = "${var.name}.${var.format}"
# Determine resource to use
is_baked = var.base_file != "" ? true : false
is_sourced = var.url != "" && ! local.is_baked ? true : false
is_created = ! local.is_baked && ! local.is_sourced ? true: false
# Volume settings
vol_name = coalesce(var.file, local.is_sourced ? local.url_file : local.name_file)
size_gb = try(var.size_gb * 1024 * 1024 * 1024, null)
id = "${var.pool_dir}/${var.pool}/${local.vol_name}"
}
# Sourced
resource "libvirt_volume" "voldef_ephemeral_sourced" {
count = local.is_sourced && ! var.persistant ? 1 : 0
name = local.vol_name
pool = var.pool
source = local.is_sourced ? var.url : null
}
# Created
resource "libvirt_volume" "voldef_ephemeral_created" {
count = local.is_created && ! var.persistant ? 1 : 0
name = local.vol_name
pool = var.pool
source = local.is_sourced ? var.url : null
size = local.size_gb
format = var.format
}
# Backed
resource "libvirt_volume" "voldef_ephemeral_baked" {
count = local.is_baked && ! var.persistant ? 1 : 0
name = local.vol_name
pool = var.pool
size = local.is_baked ? try(local.size_gb, 1) : local.size_gb
base_volume_pool = local.is_baked ? var.base_pool : null
base_volume_name = local.is_baked ? var.base_file : null
}
# Todo: Manage persistant volumes with:
# lifecycle {
# prevent_destroy = false
# }
# # Created Persistant
# resource "libvirt_volume" "voldef_ephemeral_created" {
#
# name = local.vol_name
# pool = var.pool
# source = local.is_sourced ? var.url : null
# size = local.size_gb
# format = var.format
# }
resource "null_resource" "voldef_persistant_created" {
# We only support created volumes basically
count = var.persistant ? 1 : 0
#count = local.is_created && var.persistant ? 1 : 0
#count = 0
# local ssh connection, make sure to pass variables 'user' andd 'password' on cli
# terraform apply -var user=$USER -var password=xxxxxxx
connection {
type="ssh"
# agent=var.ssh_agent # "true"
# host=var.ssh_host # "wks1.office.barbu-it.net"
# user=var.ssh_user # "root"
# password=var.password
agent = var.ssh_conn.agent
host= var.ssh_conn.host
user = var.ssh_conn.user
password = var.ssh_conn.password
#user=var.user
#password=var.password
}
provisioner "remote-exec" {
inline = [
"/opt/virt-scripts/bin/virt-vol.sh create ${local.vol_name} ${var.size_gb} ${var.pool} ${var.format}"
#"[[ ! -f '${/virt/cloud_safe/inst_storage0_data.qcow2}' ]] || \{ qemu-img create -f '${var.format}' ${local.id} '${local.size_gb}Gb; virsh pool-refresh '${var.pool}'; \}"
#"virsh vol-create-as --pool '${var.pool}' --name '${local.name_file}' --format '${var.format}' --prealloc-metadata --capacity '${local.size_gb * 100000000}'"
]
}
#provisioner "file" {
# destination = "/tmp/script.sh"
# content = templatefile(
# "${path.module}/script.sh.tpl",
# {
# "params": local.params
# "params_for_inline_command" : local.params_for_inline_command
# }
# )
#}
}
# Output
# =====================
output "volume" {
value = coalescelist(
resource.libvirt_volume.voldef_ephemeral_sourced,
resource.libvirt_volume.voldef_ephemeral_created,
resource.libvirt_volume.voldef_ephemeral_baked,
[ { id = local.id } ],
)[0]
}
output "info" {
value = {
#id = local.id,
#id = coalescelist(
id = coalescelist(
resource.libvirt_volume.voldef_ephemeral_sourced,
resource.libvirt_volume.voldef_ephemeral_created,
resource.libvirt_volume.voldef_ephemeral_baked,
[ { id = local.id } ],
)[0].id
vol_name = local.vol_name,
is_baked = local.is_baked,
is_sourced = local.is_sourced,
is_created = local.is_created,
name_url = local.url_file,
name_file = local.name_file,
format = var.format,
file = var.file,
#out = [
# resource.libvirt_volume.voldef_ephemeral_sourced,
# resource.libvirt_volume.voldef_ephemeral_baked,
# resource.libvirt_volume.voldef_ephemeral_created,
# resource.null_resource.voldef_persistant_created
#]
#volume_id = coalescelist(
# resource.libvirt_volume.voldef_ephemeral_sourced,
# resource.libvirt_volume.voldef_ephemeral_created,
# resource.libvirt_volume.voldef_ephemeral_baked,
# resource.null_resource.voldef_persistant_created,
# )[0].id
}
}

10
virt_volume/provider.tf Normal file
View File

@ -0,0 +1,10 @@
terraform {
required_providers {
libvirt = {
source = "registry.terraform.io/dmacvicar/libvirt"
version = "0.6.14"
}
}
}

74
virt_volumes/main.tf Normal file
View File

@ -0,0 +1,74 @@
# Variables
# ============
variable "tenant" {
description = "Tenant informations"
type = map
default = {
prefix = ""
}
}
variable "volumes" {
description = "List of volumes"
type = list(any)
default = []
}
variable "volumes_defaults" {
description = "Default settings for volumes"
type = map
default = {}
}
# Main
# ============
locals {
defaults = {
prefix = var.tenant.prefix
pool = "default",
pool_dir = "/virt",
size_gb = 10,
format = "qcow2"
persistant = false
base_pool = "default",
base_file = "",
url = ""
file = ""
}
volumes_defaults = merge(local.defaults, var.volumes_defaults)
}
module "cloud_volume" {
source = "../virt_volume"
for_each = { for v in var.volumes: v.name => merge(local.volumes_defaults, v) }
name = "${each.value.prefix}${each.value.name}"
pool = each.value.pool
size_gb = each.value.size_gb
format = each.value.format
persistant = each.value.persistant
base_pool = each.value.base_pool
base_file = each.value.base_file
url = each.value.url
file = each.value.file
}
# Output
# ============
output "volumes" {
value = module.cloud_volume
}

0
virt_volumes/provider.tf Normal file
View File