mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 04:40:05 +01:00
feat: mostly terraform shenanigans, but TF can now create ssh keys and servers
This commit is contained in:
2
terraform/envs/dev/.terraform.lock.hcl
generated
2
terraform/envs/dev/.terraform.lock.hcl
generated
@@ -5,7 +5,7 @@ provider "glueops/autoglue/autoglue" {
|
||||
version = "0.0.1"
|
||||
constraints = "0.0.1"
|
||||
hashes = [
|
||||
"h1:XW1zYWB6NTuE7jgJwWAkZeBBhL3Me36KE4Puy6lN6+o=",
|
||||
"h1:K5xMCf5zxZVCurwzkSEAaMv70dzBlVU8VN/q72sNyD0=",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"ssh","Source":"../../modules/ssh-key","Dir":"../../modules/ssh-key"}]}
|
||||
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"servers","Source":"../../modules/servers","Dir":"../../modules/servers"},{"Key":"ssh","Source":"../../modules/ssh-key","Dir":"../../modules/ssh-key"}]}
|
||||
@@ -27,3 +27,47 @@ output "ssh_public_keys" {
|
||||
output "ssh_written_files" {
|
||||
value = { for k, m in module.ssh : k => m.written_files }
|
||||
}
|
||||
|
||||
module "servers" {
|
||||
source = "../../modules/servers"
|
||||
# Wire the SSH key IDs so servers can reference them by name
|
||||
ssh_key_ids = { for k, m in module.ssh : k => m.id }
|
||||
|
||||
servers = {
|
||||
bastion = {
|
||||
hostname = "bastion-01"
|
||||
private_ip_address = "10.0.0.10"
|
||||
public_ip_address = "54.12.34.56" # required for role=bastion
|
||||
role = "bastion"
|
||||
ssh_user = "ubuntu"
|
||||
ssh_key_ref = "bastionKey" # points to module.ssh["bastionKey"].id
|
||||
status = "pending"
|
||||
}
|
||||
|
||||
manager1 = {
|
||||
hostname = "k3s-mgr-01"
|
||||
private_ip_address = "10.0.1.11"
|
||||
role = "manager"
|
||||
ssh_user = "ubuntu"
|
||||
ssh_key_ref = "clusterKey"
|
||||
status = "pending"
|
||||
}
|
||||
|
||||
agent1 = {
|
||||
hostname = "k3s-agent-01"
|
||||
private_ip_address = "10.0.2.21"
|
||||
role = "agent"
|
||||
ssh_user = "ubuntu"
|
||||
ssh_key_ref = "clusterKey"
|
||||
status = "pending"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output "server_ids" {
|
||||
value = module.servers.ids
|
||||
}
|
||||
|
||||
output "server_statuses" {
|
||||
value = module.servers.statuses
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,22 +2,22 @@ org_key = "org_lnJwmyyWH7JC-JgZo5v3Kw"
|
||||
org_secret = "fqd9yebGMfK6h5HSgWn4sXrwr9xlFbvbIYtNylRElMQ"
|
||||
|
||||
ssh_keys = {
|
||||
key1 = {
|
||||
name = "CI deploy key 1"
|
||||
comment = "deploy1@autoglue"
|
||||
bastionKey = {
|
||||
name = "Bastion Key"
|
||||
comment = "deploy@autoglue"
|
||||
type = "rsa"
|
||||
bits = 4096
|
||||
enable_download = true
|
||||
download_part = "both"
|
||||
download_dir = "out/key1"
|
||||
download_dir = "out/bastionKey"
|
||||
}
|
||||
key2 = {
|
||||
name = "CI deploy key 2"
|
||||
comment = "deploy2@autoglue"
|
||||
clusterKey = {
|
||||
name = "Cluster Key"
|
||||
comment = "bastion@autoglue"
|
||||
type = "ed25519" # bits ignored
|
||||
enable_download = true
|
||||
download_part = "both"
|
||||
download_dir = "out/key2"
|
||||
download_dir = "out/clusterKey"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
39
terraform/modules/servers/main.tf
Normal file
39
terraform/modules/servers/main.tf
Normal file
@@ -0,0 +1,39 @@
|
||||
locals {
|
||||
# Resolve the SSH key ID for each server:
|
||||
# Prefer explicit ssh_key_id, otherwise look up by ssh_key_ref in var.ssh_key_ids.
|
||||
resolved_ssh_key_ids = {
|
||||
for name, spec in var.servers :
|
||||
name => coalesce(
|
||||
try(spec.ssh_key_id, null),
|
||||
try(var.ssh_key_ids[spec.ssh_key_ref], null)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
resource "autoglue_server" "this" {
|
||||
for_each = var.servers
|
||||
|
||||
hostname = try(each.value.hostname, null)
|
||||
private_ip_address = each.value.private_ip_address
|
||||
public_ip_address = try(each.value.public_ip_address, null)
|
||||
role = lower(each.value.role)
|
||||
ssh_user = each.value.ssh_user
|
||||
ssh_key_id = local.resolved_ssh_key_ids[each.key]
|
||||
status = try(each.value.status, null)
|
||||
|
||||
# Client-side guards to match your API rules
|
||||
lifecycle {
|
||||
precondition {
|
||||
condition = local.resolved_ssh_key_ids[each.key] != null && local.resolved_ssh_key_ids[each.key] != ""
|
||||
error_message = "Provide either ssh_key_id or ssh_key_ref (and pass ssh_key_ids to the module)."
|
||||
}
|
||||
precondition {
|
||||
condition = lower(each.value.role) != "bastion" ? true : (try(each.value.public_ip_address, "") != "")
|
||||
error_message = "public_ip_address is required when role == \"bastion\"."
|
||||
}
|
||||
precondition {
|
||||
condition = try(each.value.status, "") == "" || contains(["pending", "provisioning", "ready", "failed"], lower(each.value.status))
|
||||
error_message = "status must be one of: pending, provisioning, ready, failed (or omitted)."
|
||||
}
|
||||
}
|
||||
}
|
||||
28
terraform/modules/servers/outputs.tf
Normal file
28
terraform/modules/servers/outputs.tf
Normal file
@@ -0,0 +1,28 @@
|
||||
output "ids" {
|
||||
description = "Map of server IDs by key."
|
||||
value = { for k, r in autoglue_server.this : k => r.id }
|
||||
}
|
||||
|
||||
output "statuses" {
|
||||
description = "Map of server statuses by key."
|
||||
value = { for k, r in autoglue_server.this : k => r.status }
|
||||
}
|
||||
|
||||
output "details" {
|
||||
description = "Selected attributes for convenience."
|
||||
value = {
|
||||
for k, r in autoglue_server.this : k => {
|
||||
id = r.id
|
||||
organization_id = r.organization_id
|
||||
hostname = r.hostname
|
||||
private_ip_address = r.private_ip_address
|
||||
public_ip_address = r.public_ip_address
|
||||
role = r.role
|
||||
ssh_user = r.ssh_user
|
||||
ssh_key_id = r.ssh_key_id
|
||||
status = r.status
|
||||
created_at = r.created_at
|
||||
updated_at = r.updated_at
|
||||
}
|
||||
}
|
||||
}
|
||||
34
terraform/modules/servers/variables.tf
Normal file
34
terraform/modules/servers/variables.tf
Normal file
@@ -0,0 +1,34 @@
|
||||
variable "servers" {
|
||||
description = <<-EOT
|
||||
Map of servers to create. Example shape:
|
||||
{
|
||||
bastion = {
|
||||
hostname = "bastion-01"
|
||||
private_ip_address = "10.0.0.10"
|
||||
public_ip_address = "54.12.34.56" # required when role = "bastion"
|
||||
role = "bastion"
|
||||
ssh_user = "ubuntu"
|
||||
ssh_key_ref = "bastionKey" # OR set ssh_key_id instead
|
||||
# ssh_key_id = "uuid-string"
|
||||
# status = "pending|provisioning|ready|failed"
|
||||
}
|
||||
}
|
||||
EOT
|
||||
type = map(object({
|
||||
hostname = optional(string)
|
||||
private_ip_address = string
|
||||
public_ip_address = optional(string)
|
||||
role = string
|
||||
ssh_user = string
|
||||
ssh_key_ref = optional(string) # name to look up in var.ssh_key_ids
|
||||
ssh_key_id = optional(string) # direct UUID (overrides ssh_key_ref if set)
|
||||
status = optional(string) # pending|provisioning|ready|failed
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "ssh_key_ids" {
|
||||
description = "Map of SSH key IDs you can reference via servers[*].ssh_key_ref."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
9
terraform/modules/servers/versions.tf
Normal file
9
terraform/modules/servers/versions.tf
Normal file
@@ -0,0 +1,9 @@
|
||||
terraform {
|
||||
required_version = ">= 1.5.0"
|
||||
|
||||
required_providers {
|
||||
autoglue = {
|
||||
source = "glueops/autoglue/autoglue"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user