Add: Initial code
This commit is contained in:
commit
335757bf44
81
cloud_project/main.tf
Normal file
81
cloud_project/main.tf
Normal 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
|
||||
#}
|
||||
|
||||
|
||||
0
cloud_project/provider.tf
Normal file
0
cloud_project/provider.tf
Normal file
14
iaas_inv_ansible/_OLD/example.inv.yml
Normal file
14
iaas_inv_ansible/_OLD/example.inv.yml
Normal 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:
|
||||
6
iaas_inv_ansible/_OLD/inventory.tmpl
Normal file
6
iaas_inv_ansible/_OLD/inventory.tmpl
Normal file
@ -0,0 +1,6 @@
|
||||
${ ip_addrs }
|
||||
%{ for addr in ip_addrs ~}
|
||||
backend ${addr}:xx
|
||||
%{ endfor ~}
|
||||
|
||||
|
||||
13
iaas_inv_ansible/_OLD/main.tf
Normal file
13
iaas_inv_ansible/_OLD/main.tf
Normal 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}"
|
||||
17
iaas_inv_ansible/_OLD/tpl_example.tpl
Normal file
17
iaas_inv_ansible/_OLD/tpl_example.tpl
Normal 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 ~}
|
||||
42
iaas_inv_ansible/ansible_host/main.tf
Normal file
42
iaas_inv_ansible/ansible_host/main.tf
Normal 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
|
||||
}
|
||||
}
|
||||
9
iaas_inv_ansible/ansible_host/provider.tf
Normal file
9
iaas_inv_ansible/ansible_host/provider.tf
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
terraform {
|
||||
required_providers {
|
||||
ansible = {
|
||||
source = "nbering/ansible"
|
||||
version = "1.0.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
34
iaas_inv_ansible/main.tf
Normal file
34
iaas_inv_ansible/main.tf
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
0
iaas_inv_ansible/provider.tf
Normal file
0
iaas_inv_ansible/provider.tf
Normal file
89
virt_cloudinit/main.tf
Normal file
89
virt_cloudinit/main.tf
Normal 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]
|
||||
#}
|
||||
8
virt_cloudinit/provider.tf
Normal file
8
virt_cloudinit/provider.tf
Normal file
@ -0,0 +1,8 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
libvirt = {
|
||||
source = "dmacvicar/libvirt"
|
||||
version = "0.6.14"
|
||||
}
|
||||
}
|
||||
}
|
||||
93
virt_flavor/main.tf
Normal file
93
virt_flavor/main.tf
Normal 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
0
virt_flavor/provider.tf
Normal file
54
virt_images/main.tf
Normal file
54
virt_images/main.tf
Normal 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
0
virt_images/provider.tf
Normal file
362
virt_instance/main.tf
Normal file
362
virt_instance/main.tf
Normal 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
12
virt_instance/provider.tf
Normal 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
112
virt_instances/main.tf
Normal 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
|
||||
# }
|
||||
# }
|
||||
|
||||
0
virt_instances/provider.tf
Normal file
0
virt_instances/provider.tf
Normal file
147
virt_namespace/main.tf
Normal file
147
virt_namespace/main.tf
Normal 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
|
||||
# }
|
||||
0
virt_namespace/provider.tf
Normal file
0
virt_namespace/provider.tf
Normal file
171
virt_network/main.tf
Normal file
171
virt_network/main.tf
Normal 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
12
virt_network/provider.tf
Normal 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"
|
||||
# }
|
||||
}
|
||||
}
|
||||
3
virt_network/templates/ferm_nat.tpl
Normal file
3
virt_network/templates/ferm_nat.tpl
Normal file
@ -0,0 +1,3 @@
|
||||
[nat]
|
||||
driver = ${ driver }
|
||||
device = ${ device }
|
||||
8
virt_network/templates/ipvs_config.tpl
Normal file
8
virt_network/templates/ipvs_config.tpl
Normal 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
73
virt_networks/main.tf
Normal 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
|
||||
}
|
||||
|
||||
|
||||
0
virt_networks/provider.tf
Normal file
0
virt_networks/provider.tf
Normal file
194
virt_os/main.tf
Normal file
194
virt_os/main.tf
Normal 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
0
virt_os/provider.tf
Normal file
57
virt_os/templates/cloud_debian_generic.yml
Normal file
57
virt_os/templates/cloud_debian_generic.yml
Normal 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
55
virt_pools/main.tf
Normal 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
8
virt_pools/provider.tf
Normal file
@ -0,0 +1,8 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
libvirt = {
|
||||
source = "dmacvicar/libvirt"
|
||||
version = "0.6.14"
|
||||
}
|
||||
}
|
||||
}
|
||||
262
virt_volume/main.tf
Normal file
262
virt_volume/main.tf
Normal 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
10
virt_volume/provider.tf
Normal 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
74
virt_volumes/main.tf
Normal 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
0
virt_volumes/provider.tf
Normal file
Loading…
x
Reference in New Issue
Block a user