diff --git a/nomad/.gitignore b/nomad/.gitignore index 54bf0af..74e2eb5 100644 --- a/nomad/.gitignore +++ b/nomad/.gitignore @@ -1,3 +1,4 @@ roles/ venv/ vault-keys.json +nomad_bootstrap.json diff --git a/nomad/.terraform.lock.hcl b/nomad/.terraform.lock.hcl index 083e649..9845800 100644 --- a/nomad/.terraform.lock.hcl +++ b/nomad/.terraform.lock.hcl @@ -36,3 +36,21 @@ provider "registry.terraform.io/hashicorp/nomad" { "zh:d87c12a6a7768f2b6c2a59495c7dc00f9ecc52b1b868331d4c284f791e278a1e", ] } + +provider "registry.terraform.io/hashicorp/vault" { + version = "3.3.1" + hashes = [ + "h1:SOTmxGynxFf1hECFq0/FGujGQZNktePze/4mfdR/iiU=", + "zh:3e1866037f43c1083ff825dce2a9e3853c757bb0121c5ae528ee3cf3f99b4113", + "zh:49636cc5c4939134e098c4ec0163c41fae103f24d7e1e8fc0432f8ad93d596a0", + "zh:5258a7001719c4aeb84f4c4da7115b795da4794754938a3c4176a4b578fe93a1", + "zh:7461738691e2e8ea91aba73d4351cfbc30fcaedcf0e332c9d35ef215f93aa282", + "zh:815529478e33a6727273b08340a4c62c9aeb3da02abf8f091bb4f545c8451fce", + "zh:8e6fede9f5e25b507faf6cacd61b997035b8b62859245861149ddb2990ada8eb", + "zh:9acc2387084b9c411e264c4351633bc82f9c4e420f8e6bbad9f87b145351f929", + "zh:b9e4af3b06386ceed720f0163a1496088c154aa1430ae072c525ffefa4b37891", + "zh:c7d5dfb8f8536694db6740e2a4afd2d681b60b396ded469282524c62ce154861", + "zh:d0850be710c6fd682634a2f823beed0164231cc873b1dc09038aa477c926f57c", + "zh:e90c2cba9d89db5eab295b2f046f24a53f23002bcfe008633d398fb3fa16d941", + ] +} diff --git a/nomad/acls.tf b/nomad/acls.tf new file mode 100644 index 0000000..0eeee74 --- /dev/null +++ b/nomad/acls.tf @@ -0,0 +1,5 @@ +# resource "nomad_acl_policy" "create_post_bootstrap_policy" { +# name = "anonymous" +# description = "Anon RW" +# rules_hcl = file("${path.module}/acls/nomad-anon-bootstrap.hcl") +# } diff --git a/nomad/acls/nomad-anon-bootstrap.hcl b/nomad/acls/nomad-anon-bootstrap.hcl new file mode 100644 index 0000000..9fe3564 --- /dev/null +++ b/nomad/acls/nomad-anon-bootstrap.hcl @@ -0,0 +1,24 @@ +namespace "*" { + policy = "write" + capabilities = ["alloc-node-exec"] +} + +agent { + policy = "write" +} + +operator { + policy = "write" +} + +quota { + policy = "write" +} + +node { + policy = "write" +} + +host_volume "*" { + policy = "write" +} diff --git a/nomad/providers.tf b/nomad/providers.tf new file mode 100644 index 0000000..0dd8bd0 --- /dev/null +++ b/nomad/providers.tf @@ -0,0 +1,36 @@ +# Configure Consul provider +provider "consul" { + address = var.consul_address +} + +# Get Nomad client from Consul +data "consul_service" "nomad" { + name = "nomad-client" +} + +# Get Vault client from Consul +data "consul_service" "vault" { + name = "vault" + tag = "active" +} + +locals { + # Get Nomad address from Consul + nomad_node = data.consul_service.nomad.service[0] + nomad_node_address = "http://${local.nomad_node.node_address}:${local.nomad_node.port}" + + # Get Vault address from Consul + vault_node = data.consul_service.vault.service[0] + vault_node_address = "http://${local.vault_node.node_address}:${local.vault_node.port}" +} + +# Configure the Nomad provider +provider "nomad" { + address = local.nomad_node_address + region = "global" +} + +# Configure the Vault provider +provider "vault" { + address = local.vault_node_address +} diff --git a/nomad/services.tf b/nomad/services.tf index 595b0fb..83b29b9 100644 --- a/nomad/services.tf +++ b/nomad/services.tf @@ -1,37 +1,3 @@ -# Configure Consul provider -variable "consul_address" { - type = string - default = "http://nomad0.thefij:8500" -} - -variable "base_hostname" { - type = string - description = "Base hostname to serve content from" - default = "dev.homelab" -} - -provider "consul" { - address = var.consul_address -} - -# Get Nomad client from Consul -data "consul_service" "read-nomad-cluster" { - name = "nomad-client" -} - -locals { - nomad_node = data.consul_service.read-nomad-cluster.service[0] - nomad_node_address = "http://${local.nomad_node.node_address}:${local.nomad_node.port}" -} - -# Configure the Nomad provider -provider "nomad" { - address = local.nomad_node_address - region = "global" -} - -# Define services as modules - module "mysql-server" { source = "./mysql" } @@ -70,7 +36,7 @@ resource "nomad_job" "whoami" { hcl2 { enabled = true vars = { - "count" = "${2 * length(data.consul_service.read-nomad-cluster.service)}", + "count" = "${2 * length(data.consul_service.nomad.service)}", } } @@ -98,4 +64,3 @@ resource "consul_config_entry" "global_access" { ] }) } - diff --git a/nomad/setup-cluster.yml b/nomad/setup-cluster.yml index 390eb8a..d741b12 100644 --- a/nomad/setup-cluster.yml +++ b/nomad/setup-cluster.yml @@ -35,7 +35,6 @@ become: true - tasks: - name: Start Consul systemd: @@ -197,3 +196,71 @@ systemd: state: started name: nomad + +- name: Bootstrap Nomad ACLs + hosts: nomad_instances + + tasks: + - name: Bootstrap ACLs + command: + argv: + - "nomad" + - "acl" + - "bootstrap" + - "-json" + run_once: true + ignore_errors: true + register: bootstrap_result + + - name: Save bootstrap result + copy: + content: "{{ bootstrap_result.stdout }}" + dest: "./nomad_bootstrap.json" + when: bootstrap_result is succeeded + delegate_to: localhost + run_once: true + + - name: Look for policy + command: + argv: + - nomad + - acl + - policy + - list + run_once: true + register: policies + + - name: Read secret + command: + argv: + - jq + - -r + - .SecretID + - nomad_bootstrap.json + delegate_to: localhost + run_once: true + register: read_secretid + + - name: Copy policy + copy: + src: ./acls/nomad-anon-bootstrap.hcl + dest: /tmp/anonymous.policy.hcl + delegate_to: "{{ play_hosts[0] }}" + register: anon_policy + run_once: true + + - name: Create anon-policy + command: + argv: + - nomad + - acl + - policy + - apply + - -description="Anon RW" + - anonymous + - /tmp/anonymous.policy.hcl + environment: + NOMAD_TOKEN: "{{ read_secretid.stdout }}" + when: policies.stdout == "No policies found" or anon_policy.changed + delegate_to: "{{ play_hosts[0] }}" + run_once: true diff --git a/nomad/vars.tf b/nomad/vars.tf new file mode 100644 index 0000000..8c98c91 --- /dev/null +++ b/nomad/vars.tf @@ -0,0 +1,16 @@ +variable "consul_address" { + type = string + default = "http://nomad0.thefij:8500" +} + +variable "base_hostname" { + type = string + description = "Base hostname to serve content from" + default = "dev.homelab" +} + +variable "nomad_secret_id" { + type = string + description = "Secret ID for ACL bootstrapped Nomad" + sensitive = true +}