Compare commits

...

2 Commits

Author SHA1 Message Date
7658cfd0fe WIP: Set up step-ca
Unsure of the best way to setup bootstrapping the system. Do I run an
ansible playbook to generate certificates offline and then bootstrap
with that? Can I bring it online after and schedule with Nomad?
2022-03-22 16:39:39 -07:00
f2ce718b33 Add Nomad ACL bootstrap 2022-03-21 21:26:04 -07:00
12 changed files with 234 additions and 37 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
roles/ roles/
venv/ venv/
vault-keys.json vault-keys.json
nomad_bootstrap.json

18
.terraform.lock.hcl generated
View File

@ -36,3 +36,21 @@ provider "registry.terraform.io/hashicorp/nomad" {
"zh:d87c12a6a7768f2b6c2a59495c7dc00f9ecc52b1b868331d4c284f791e278a1e", "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",
]
}

5
acls.tf Normal file
View File

@ -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")
# }

View File

@ -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"
}

View File

@ -13,6 +13,12 @@ all:
group: "bin" group: "bin"
mode: "0755" mode: "0755"
read_only: false read_only: false
- name: step-ca-data
path: /srv/volumes/step-ca-data
owner: "root"
group: "bin"
mode: "0700"
read_only: false
# consul_auto_encrypt: # consul_auto_encrypt:
# enabled: true # enabled: true
# dns_san: ["services.thefij"] # dns_san: ["services.thefij"]
@ -31,3 +37,7 @@ all:
vault_instances: vault_instances:
children: children:
servers: {} servers: {}
ca_servers:
hosts:
nomad0.thefij:
step_path: /srv/volumes/step-ca-data

1
ca/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
step_path

19
ca/Makefile Normal file
View File

@ -0,0 +1,19 @@
STEPPATH ?= ./step_path
.PHONY: bootstrap
bootstrap: $(STEPPATH)/config/ca.json
$(STEPPATH)/config/ca.json:
env STEPPATH=$(STEPPATH) \
step ca init \
--ssh \
--deployment-type standalone \
--name TheFij \
--dns ca.thefij.rocks \
--address 0.0.0.0:9443 \
--provisioner ian@iamthefij.com
.PHONY: run
run: $(STEPPATH)/config/ca.json
env STEPPATH=$(STEPPATH) \
step-ca $(STEPPATH)/config/ca.json

35
ca/setup-ca.yml Normal file
View File

@ -0,0 +1,35 @@
---
- name: Set up CA
hosts: ca_servers
become: true
tasks:
- name: Create step_path
file:
path: "{{ step_path }}"
state: directory
owner: root
mode: "0700"
- name: Install step-ca
include_role:
name: maxhoesel.smallstep.step_ca
vars:
step_ca_name: TheFij CA
step_ca_root_password: ...
step_ca_intermediate_password: ...
step_cli_steppath: "{{ step_path }}"
- name: Read fingerprint
command: "step-cli certificate fingerprint {{ step_path }}/certs/root_ca.crt"
register: root_ca_fp
- name: Bootstrap other hosts
hosts: servers
tasks:
- name: Boostrap hosts to trust CA
include_role:
name: maxhoesel.smallstep.step_bootstrap_host
vars:
step_bootstrap_ca_url: http

36
providers.tf Normal file
View File

@ -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
}

View File

@ -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" { module "mysql-server" {
source = "./mysql" source = "./mysql"
} }
@ -70,7 +36,7 @@ resource "nomad_job" "whoami" {
hcl2 { hcl2 {
enabled = true enabled = true
vars = { 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" {
] ]
}) })
} }

View File

@ -35,7 +35,6 @@
become: true become: true
tasks: tasks:
- name: Start Consul - name: Start Consul
systemd: systemd:
@ -197,3 +196,71 @@
systemd: systemd:
state: started state: started
name: nomad 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

16
vars.tf Normal file
View File

@ -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
}