added providers, fleshed out terraform
This commit is contained in:
parent
9b028b095e
commit
8f3291499f
|
|
@ -0,0 +1,10 @@
|
||||||
|
- name: Log evidence
|
||||||
|
include_role:
|
||||||
|
name: evidence_logger
|
||||||
|
vars:
|
||||||
|
log_file: "dns_check.log"
|
||||||
|
log_content: |
|
||||||
|
mail.example.com -> 203.0.113.10
|
||||||
|
auth.example.com -> 203.0.113.11
|
||||||
|
summary_entry: "✅ DNS resolution for example.com"
|
||||||
|
validation_entry: "DNS check completed and passed for fqdn_root: example.com"
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
apt update && apt install -y git python3-pip curl ufw
|
set -e
|
||||||
pip3 install ansible
|
|
||||||
ufw allow OpenSSH
|
echo "🔧 Initializing Terraform..."
|
||||||
ufw --force enable
|
terraform init
|
||||||
git clone https://github.com/mtkell/open-cmmc-stack.git /opt/open-cmmc-stack
|
|
||||||
cd /opt/open-cmmc-stack/ansible
|
echo "📐 Running Terraform plan..."
|
||||||
ansible-playbook -i localhost, secure_ubuntu.yml
|
terraform plan -var-file=terraform.tfvars
|
||||||
|
|
||||||
|
echo "🚀 Applying Terraform configuration..."
|
||||||
|
terraform apply -auto-approve -var-file=terraform.tfvars
|
||||||
|
|
||||||
|
echo "✅ Done. Review outputs below:"
|
||||||
|
terraform output
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,36 @@
|
||||||
provider "digitalocean" {
|
terraform {
|
||||||
token = var.do_token
|
required_version = ">= 1.3.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
local = {
|
||||||
|
source = "hashicorp/local"
|
||||||
|
version = "~> 2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "digitalocean_droplet" "secure_host" {
|
provider "local" {}
|
||||||
name = "cmmc-hardened"
|
|
||||||
region = "nyc3"
|
|
||||||
size = "s-2vcpu-4gb"
|
|
||||||
image = "ubuntu-22-04-x64"
|
|
||||||
ssh_keys = [var.ssh_fingerprint]
|
|
||||||
user_data = file("${path.module}/bootstrap.sh")
|
|
||||||
|
|
||||||
tags = ["cmmc", "secure-host"]
|
locals {
|
||||||
|
services = var.vm_definitions
|
||||||
}
|
}
|
||||||
|
|
||||||
output "droplet_ip" {
|
module "vm" {
|
||||||
value = digitalocean_droplet.secure_host.ipv4_address
|
source = "./modules/vm"
|
||||||
|
for_each = local.services
|
||||||
|
|
||||||
|
service_name = each.key
|
||||||
|
provider = var.infrastructure_provider
|
||||||
|
region = each.value.region
|
||||||
|
tags = each.value.tags
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a DNS A record for each deployed service
|
||||||
|
module "dns" {
|
||||||
|
source = "./modules/dns_record"
|
||||||
|
for_each = local.services
|
||||||
|
|
||||||
|
zone_id = var.cloudflare_zone_id
|
||||||
|
subdomain = each.key
|
||||||
|
ip_address = module.vm[each.key].ip_address
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
resource "cloudflare_record" "dns" {
|
||||||
|
zone_id = var.zone_id
|
||||||
|
name = var.subdomain
|
||||||
|
type = "A"
|
||||||
|
value = var.ip_address
|
||||||
|
ttl = 300
|
||||||
|
proxied = false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
output "fqdn" {
|
||||||
|
value = "${var.subdomain}.${var.root_domain}"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
variable "zone_id" {
|
||||||
|
description = "Cloudflare Zone ID"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subdomain" {
|
||||||
|
description = "Subdomain to create (e.g., mail, auth)"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ip_address" {
|
||||||
|
description = "Public IP address to point the A record to"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
resource "aws_instance" "vm" {
|
||||||
|
count = var.provider == "aws" ? 1 : 0
|
||||||
|
ami = var.aws_ami
|
||||||
|
instance_type = "t3.micro"
|
||||||
|
key_name = var.ssh_key_name
|
||||||
|
tags = merge(
|
||||||
|
var.tags,
|
||||||
|
{ Name = "open-cmmc-${var.service_name}" }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
resource "azurerm_linux_virtual_machine" "vm" {
|
||||||
|
count = var.provider == "azure" ? 1 : 0
|
||||||
|
name = "open-cmmc-${var.service_name}"
|
||||||
|
resource_group_name = var.azure_resource_group
|
||||||
|
location = var.region
|
||||||
|
size = "Standard_B1s"
|
||||||
|
admin_username = "ubuntu"
|
||||||
|
|
||||||
|
admin_ssh_key {
|
||||||
|
username = "ubuntu"
|
||||||
|
public_key = var.ssh_public_key
|
||||||
|
}
|
||||||
|
|
||||||
|
network_interface_ids = [var.azure_nic_id]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
resource "digitalocean_droplet" "vm" {
|
||||||
|
count = var.provider == "digitalocean" ? 1 : 0
|
||||||
|
name = "open-cmmc-${var.service_name}"
|
||||||
|
region = var.region
|
||||||
|
image = "ubuntu-22-04-x64"
|
||||||
|
size = "s-1vcpu-1gb"
|
||||||
|
ssh_keys = var.ssh_keys
|
||||||
|
tags = [for tag_key, tag_value in var.tags : "${tag_key}:${tag_value}"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
resource "google_compute_instance" "vm" {
|
||||||
|
count = var.provider == "gcp" ? 1 : 0
|
||||||
|
name = "open-cmmc-${var.service_name}"
|
||||||
|
machine_type = "e2-medium"
|
||||||
|
zone = var.gcp_zone
|
||||||
|
|
||||||
|
boot_disk {
|
||||||
|
initialize_params {
|
||||||
|
image = "ubuntu-os-cloud/ubuntu-2204-lts"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
network = "default"
|
||||||
|
access_config {} # This allocates a one-to-one NAT IP
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
ssh-keys = "ubuntu:${var.ssh_public_key}"
|
||||||
|
}
|
||||||
|
|
||||||
|
tags = [for tag_key, tag_value in var.tags : "${tag_key}:${tag_value}"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
resource "digitalocean_droplet" "vm" {
|
||||||
|
name = "open-cmmc-${var.service_name}"
|
||||||
|
region = var.region
|
||||||
|
size = "s-1vcpu-1gb"
|
||||||
|
image = "ubuntu-22-04-x64"
|
||||||
|
|
||||||
|
tags = [for tag_key, tag_value in var.tags : "${tag_key}:${tag_value}"]
|
||||||
|
|
||||||
|
ssh_keys = var.ssh_keys
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = [image]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
output "ip_address" {
|
||||||
|
value = (
|
||||||
|
var.provider == "digitalocean" && length(digitalocean_droplet.vm) > 0 ? digitalocean_droplet.vm[0].ipv4_address :
|
||||||
|
var.provider == "aws" && length(aws_instance.vm) > 0 ? aws_instance.vm[0].public_ip :
|
||||||
|
var.provider == "azure" && length(azurerm_linux_virtual_machine.vm) > 0 ? azurerm_linux_virtual_machine.vm[0].public_ip_address :
|
||||||
|
var.provider == "gcp" && length(google_compute_instance.vm) > 0 ? google_compute_instance.vm[0].network_interface[0].access_config[0].nat_ip :
|
||||||
|
var.provider == "proxmox" ? proxmox_vm_qemu.vm[0].ipconfig0 :
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
resource "proxmox_vm_qemu" "vm" {
|
||||||
|
count = var.provider == "proxmox" ? 1 : 0
|
||||||
|
name = "open-cmmc-${var.service_name}"
|
||||||
|
target_node = var.proxmox_node
|
||||||
|
clone = var.proxmox_template
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
variable "ssh_keys" {
|
||||||
|
description = "List of DigitalOcean SSH key fingerprints or IDs"
|
||||||
|
type = list(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "aws_ami" {
|
||||||
|
description = "AMI ID to use for AWS EC2 instance"
|
||||||
|
type = string
|
||||||
|
default = "ami-0c55b159cbfafe1f0" # Ubuntu 22.04 in us-east-1 (example)
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_key_name" {
|
||||||
|
description = "AWS SSH key pair name"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "azure_resource_group" {
|
||||||
|
description = "Azure resource group name"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "azure_nic_id" {
|
||||||
|
description = "Azure network interface ID"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_public_key" {
|
||||||
|
description = "Public SSH key for Azure admin login"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "gcp_project_id" {
|
||||||
|
description = "Google Cloud Project ID"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "gcp_region" {
|
||||||
|
description = "Google Cloud region"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "gcp_zone" {
|
||||||
|
description = "Google Cloud zone"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "gcp_credentials_file" {
|
||||||
|
description = "Path to GCP service account JSON key file"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Output all service names
|
||||||
|
output "vm_services" {
|
||||||
|
value = keys(module.vm)
|
||||||
|
description = "List of deployed service names"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output tags per service
|
||||||
|
output "vm_tags" {
|
||||||
|
value = {
|
||||||
|
for service, mod in module.vm : service => mod.vm_service_tag
|
||||||
|
}
|
||||||
|
description = "Tags assigned per service VM"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Placeholder for service-level info until actual providers are implemented
|
||||||
|
output "vm_placeholders" {
|
||||||
|
value = {
|
||||||
|
for service, mod in module.vm : service => {
|
||||||
|
service_tag = mod.vm_service_tag
|
||||||
|
ip_address = "PLACEHOLDER"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
description = "Service-level IPs and tags (will be replaced with real outputs later)"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
provider "digitalocean" {
|
||||||
|
token = var.digitalocean_token
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optionally configure default region or other settings here
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
provider "google" {
|
||||||
|
project = var.gcp_project_id
|
||||||
|
region = var.gcp_region
|
||||||
|
zone = var.gcp_zone
|
||||||
|
credentials = file(var.gcp_credentials_file)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
provider "proxmox" {
|
||||||
|
pm_api_url = var.proxmox_api_url
|
||||||
|
pm_user = var.proxmox_user
|
||||||
|
pm_password = var.proxmox_password
|
||||||
|
pm_tls_insecure = true
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,62 @@
|
||||||
do_token = "your_digitalocean_token_here"
|
# Base domain for TLS and reverse proxy
|
||||||
ssh_fingerprint = "your_local_ssh_key_fingerprint"
|
fqdn_root = "example.com"
|
||||||
|
|
||||||
|
# Choose your provider: aws, azure, gcp, digitalocean, proxmox
|
||||||
|
infrastructure_provider = "digitalocean"
|
||||||
|
|
||||||
|
# Define which services should be deployed, and where
|
||||||
|
vm_definitions = {
|
||||||
|
mail = {
|
||||||
|
region = "nyc3"
|
||||||
|
tags = {
|
||||||
|
role = "mail"
|
||||||
|
purpose = "email"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
files = {
|
||||||
|
region = "nyc3"
|
||||||
|
tags = {
|
||||||
|
role = "file_storage"
|
||||||
|
purpose = "nextcloud"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auth = {
|
||||||
|
region = "nyc3"
|
||||||
|
tags = {
|
||||||
|
role = "identity"
|
||||||
|
purpose = "keycloak"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# infrastructure_provider = "aws"
|
||||||
|
# aws_ami = "ami-0c55b159cbfafe1f0"
|
||||||
|
# ssh_key_name = "my-aws-keypair"
|
||||||
|
|
||||||
|
# infrastructure_provider = "azure"
|
||||||
|
# azure_resource_group = "my-cmmc-resources"
|
||||||
|
# azure_nic_id = "/subscriptions/.../resourceGroups/.../providers/Microsoft.Network/networkInterfaces/..."
|
||||||
|
# ssh_public_key = "ssh-rsa AAAAB3Nza...your-key-here"
|
||||||
|
|
||||||
|
# infrastructure_provider = "gcp"
|
||||||
|
# gcp_project_id = "your-gcp-project-id"
|
||||||
|
# gcp_region = "us-central1"
|
||||||
|
# gcp_zone = "us-central1-a"
|
||||||
|
# gcp_credentials_file = "gcp-service-account.json"
|
||||||
|
# ssh_public_key = "ssh-rsa AAAAB3Nza...your-key-here"
|
||||||
|
|
||||||
|
# ⚙️ Proxmox Example (uncomment to use)
|
||||||
|
# infrastructure_provider = "proxmox"
|
||||||
|
# proxmox_api_url = "https://192.168.1.100:8006/api2/json"
|
||||||
|
# proxmox_user = "root@pam"
|
||||||
|
# proxmox_password = "yourpassword"
|
||||||
|
# proxmox_node = "pve"
|
||||||
|
# proxmox_template = "ubuntu-22.04-template"
|
||||||
|
# ssh_public_key = "ssh-rsa AAAAB3Nza...your-key-here"
|
||||||
|
|
||||||
|
# dns_provider = "cloudflare"
|
||||||
|
# fqdn_root = "example.com"
|
||||||
|
# cloudflare_api_token = "your-cloudflare-api-token"
|
||||||
|
# cloudflare_zone_id = "your-cloudflare-zone-id"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,45 @@
|
||||||
variable "do_token" {
|
variable "fqdn_root" {
|
||||||
description = "DigitalOcean API token"
|
description = "Base domain used for subdomain routing (e.g., example.com)"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "infrastructure_provider" {
|
||||||
|
description = "Target infrastructure provider (e.g., aws, azure, gcp, digitalocean, proxmox)"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_definitions" {
|
||||||
|
description = "Map of service names to regions and tags"
|
||||||
|
type = map(object({
|
||||||
|
region = string
|
||||||
|
tags = map(string)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "digitalocean_token" {
|
||||||
|
description = "API token for DigitalOcean"
|
||||||
type = string
|
type = string
|
||||||
sensitive = true
|
sensitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "ssh_fingerprint" {
|
variable "proxmox_api_url" { ... }
|
||||||
description = "Your public SSH key fingerprint registered with DigitalOcean"
|
variable "proxmox_user" { ... }
|
||||||
|
variable "proxmox_password" { ... }
|
||||||
|
variable "proxmox_node" { ... }
|
||||||
|
variable "proxmox_template" { ... }
|
||||||
|
|
||||||
|
variable "fqdn_root" {
|
||||||
|
description = "Base domain for DNS records (e.g., example.com)"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cloudflare_api_token" {
|
||||||
|
description = "API token for Cloudflare with DNS edit permissions"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cloudflare_zone_id" {
|
||||||
|
description = "Zone ID of the domain in Cloudflare"
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue