feat: import current status

- import pki, ssh, kv, rundeck engines
- deploy all roles from terraform
- deploy all policies from terraform
- deploy all approles from terraform
This commit is contained in:
Ben Vincent 2024-09-23 22:01:18 +10:00
parent 4bee3b8313
commit 14790f8277
26 changed files with 399 additions and 1 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.terraform
.terraform.lock.hcl
env

View File

@ -1,3 +1,37 @@
# terraform-vault
A repository to manage the configuration of Vault secret engines, authentication modes and policies.
A repository to manage the configuration of Vault secret engines, authentication modes and policies.
# Usage
1. Initialize Terraform
Once you have your backend block configured, you need to initialize your Terraform working directory to configure the backend:
```bash
terraform init
```
This command initializes the backend and checks the connection to Consul. If everything is set up correctly, Terraform will start using Consul as its backend for storing the state.
2. Common terraform init Errors
If you encounter errors while running terraform init, check the following:
Consul server is reachable: Make sure that the address is correct and that you can connect to the Consul server.
Consul token (if using ACLs): Verify that the token has the correct permissions to write to the specified path in the Consul KV store.
3. Example Consul KV Structure
In Consul, the state file will be stored in the KV store under the specified path:
```bash
terraform/state
```
You can check the Consul KV store by accessing the Consul UI or using the consul kv command to see the stored Terraform state:
```bash
consul kv get terraform/state
```

View File

@ -0,0 +1,14 @@
resource "vault_approle_auth_backend_role" "certmanager" {
role_name = "certmanager"
bind_secret_id = false
token_policies = ["certmanager"]
token_ttl = 30
token_max_ttl = 30
token_bound_cidrs = [
"198.18.17.3/32",
"198.18.13.32/32",
"198.18.13.33/32",
"198.18.13.34/32",
"198.18.13.46/32"
]
}

View File

@ -0,0 +1,9 @@
resource "vault_approle_auth_backend_role" "rundeck-role" {
role_name = "rundeck-role"
bind_secret_id = true
token_policies = ["rundeck"]
token_ttl = 1 * 3600
token_max_ttl = 4 * 3600
token_bound_cidrs = ["198.18.13.59/32"]
secret_id_bound_cidrs = ["198.18.13.59/32"]
}

View File

@ -0,0 +1,14 @@
resource "vault_approle_auth_backend_role" "sshsign-host-role" {
role_name = "sshsign-host-role"
bind_secret_id = false
token_policies = ["sshsign-host-policy"]
token_ttl = 30
token_max_ttl = 30
token_bound_cidrs = [
"198.18.17.3/32",
"198.18.13.32/32",
"198.18.13.33/32",
"198.18.13.34/32",
"198.18.13.46/32"
]
}

17
auth_approle_sshsigner.tf Normal file
View File

@ -0,0 +1,17 @@
resource "vault_approle_auth_backend_role" "sshsigner" {
role_name = "sshsigner"
bind_secret_id = false
token_policies = [
"sshsigner",
"sshca_signhost"
]
token_ttl = 30
token_max_ttl = 30
token_bound_cidrs = [
"198.18.17.3/32",
"198.18.13.32/32",
"198.18.13.33/32",
"198.18.13.34/32",
"198.18.13.46/32"
]
}

7
auth_backend_approle.tf Normal file
View File

@ -0,0 +1,7 @@
#----------------------------
# Enable approle auth method
#----------------------------
resource "vault_auth_backend" "approle" {
type = "approle"
path = "approle"
}

13
auth_backend_ldap.tf Normal file
View File

@ -0,0 +1,13 @@
#--------------------------------
# Enable ldap auth method
#--------------------------------
resource "vault_ldap_auth_backend" "ldap" {
path = "ldap"
url = "ldap://ldap.query.consul"
userdn = "dc=main,dc=unkin,dc=net"
userattr = "uid"
upndomain = "main.unkin.net"
discoverdn = false
groupdn = "ou=groups,dc=main,dc=unkin,dc=net"
groupfilter = "(memberOf=ou=vault_access,ou=groups,dc=main,dc=unkin,dc=net)"
}

15
engine_kv.tf Normal file
View File

@ -0,0 +1,15 @@
#--------------------------------------------------------------
# kv
# create engine
#--------------------------------------------------------------
resource "vault_mount" "kv" {
path = "kv"
type = "kv"
listing_visibility = "hidden"
max_lease_ttl_seconds = 0
external_entropy_access = false
seal_wrap = false
options = {
version = "2"
}
}

49
engine_pki_int.tf Normal file
View File

@ -0,0 +1,49 @@
#--------------------------------------------------------------
# pki_int
# create engine
# generate intermediate csa
# sign the intermediate against rootca
# set the signed intermediate cert in the pki_int engine
#--------------------------------------------------------------
resource "vault_mount" "pki_int" {
path = "pki_int"
type = "pki"
description = "PKI Intermediate CA"
max_lease_ttl_seconds = 43800 * 3600 # 43800 hours
}
## Generate the intermediate CSR
#resource "vault_pki_secret_backend_intermediate_cert_request" "pki_int_intermediate" {
# backend = vault_mount.pki_int.path
# common_name = "unkin.net Intermediate Authority"
# format = "pem"
# type = "internal"
#}
#
## Sign the intermediate CSR using the root CA
#resource "vault_generic_endpoint" "pki_root_sign_intermediate" {
# path = "${vault_mount.pki_root.path}/root/sign-intermediate"
#
# data_json = jsonencode({
# csr = vault_pki_secret_backend_intermediate_cert_request.pki_int_intermediate.csr,
# format = "pem_bundle",
# ttl = "43800h",
# issuer_ref = "UNKIN_ROOTCA_2024"
# })
#}
#
## Decode the certificate from the response
#locals {
# intermediate_signed_cert = vault_generic_endpoint.pki_root_sign_intermediate.write_data["certificate"]
#}
#
## Set the signed intermediate certificate
#resource "vault_pki_secret_backend_intermediate_set_signed" "pki_int_set_signed" {
# backend = vault_mount.pki_int.path
# certificate = local.intermediate_signed_cert
#}
#data "vault_pki_secret_backend_issuer" "pki_int_issuer" {
# backend = vault_mount.pki_int.path
# issuer_ref = data.vault_pki_secret_backend_root_cert.root.issuer_id
#}

39
engine_pki_root.tf Normal file
View File

@ -0,0 +1,39 @@
#-------------------------------------------
# pki_root:
# create engine
# generate rootca certificate
# read the issuer
# configure the pki urls
#-------------------------------------------
resource "vault_mount" "pki_root" {
path = "pki_root"
type = "pki"
description = "PKI Root CA"
max_lease_ttl_seconds = 87600 * 3600 # 87600h
}
#resource "vault_pki_secret_backend_root_cert" "pki_root_root_cert" {
# backend = vault_mount.pki_root.path
# common_name = "unkin.net"
# issuer_name = "UNKIN_ROOTCA_2024"
# ttl = 87600 * 3600
# format = "pem"
# type = "internal"
#}
#
#output "root_certificate" {
# value = vault_pki_secret_backend_root_cert.pki_root_root_cert.certificate
# sensitive = true
#}
data "vault_pki_secret_backend_issuer" "pki_root_issuer" {
backend = vault_mount.pki_root.path
issuer_ref = "default"
}
resource "vault_pki_secret_backend_config_urls" "pki_root_urls" {
backend = vault_mount.pki_root.path
issuing_certificates = ["${local.vault_addr}/v1/pki_root/ca"]
crl_distribution_points = ["${local.vault_addr}/v1/pki_root/crl"]
}

14
engine_rundeck.tf Normal file
View File

@ -0,0 +1,14 @@
#--------------------------------------------------------------
# rundeck
# create engine
#--------------------------------------------------------------
resource "vault_mount" "rundeck" {
path = "rundeck"
type = "kv"
max_lease_ttl_seconds = 0
external_entropy_access = false
seal_wrap = false
options = {
version = "2"
}
}

18
engine_ssh-host-signer.tf Normal file
View File

@ -0,0 +1,18 @@
#--------------------------------------------------------------
# ssh-host-signer
# create engine
# generate ca cert
# tune the ssh engine
#--------------------------------------------------------------
#resource "vault_mount" "ssh_host_signer" {
# path = "ssh-host-signer"
# type = "ssh"
# description = "SSH Host Signing Engine"
# max_lease_ttl_seconds = 87600 * 3600
#}
#
#resource "vault_ssh_secret_backend_ca" "ssh_host_signer_ca" {
# backend = vault_mount.ssh_host_signer.path
# generate_signing_key = false # change to true for new configuration
# key_type = "ssh-rsa"
#}

18
engine_sshca.tf Normal file
View File

@ -0,0 +1,18 @@
#--------------------------------------------------------------
# ssh
# create engine
# generate ca cert
# tune the ssh engine
#--------------------------------------------------------------
resource "vault_mount" "sshca" {
path = "sshca"
type = "ssh"
description = "SSH CA Engine"
max_lease_ttl_seconds = 87600 * 3600
}
resource "vault_ssh_secret_backend_ca" "ssh_ca" {
backend = vault_mount.sshca.path
generate_signing_key = true
key_type = "ssh-rsa"
}

31
main.tf Normal file
View File

@ -0,0 +1,31 @@
#-------------------------------------------
# locals
#-------------------------------------------
locals {
vault_addr = "https://vault.service.consul:8200"
}
#-----------------------------------------------------------------------------
# Configure this provider through the environment variables:
# - VAULT_ADDR
# - VAULT_TOKEN
#-----------------------------------------------------------------------------
provider "vault" {
address = local.vault_addr
}
#------------------------------------------------------------------------------
# Use remote state file and encrypt it since your state files may contains
# sensitive data.
# export CONSUL_HTTP_TOKEN=<your-token>
#------------------------------------------------------------------------------
terraform {
backend "consul" {
address = "https://consul.service.consul"
path = "infra/terraform/state"
scheme = "https"
lock = true
ca_file = "/etc/pki/tls/certs/ca-bundle.crt"
}
}

31
policies.tf Normal file
View File

@ -0,0 +1,31 @@
# Define directories for different policy sets
locals {
policy_directories = {
pki_int = "policies/pki_int"
pki_root = "policies/pki_root"
rundeck = "policies/rundeck"
ssh_host_signer = "policies/ssh-host-signer"
sshca = "policies/sshca"
}
}
# Load policy files from each directory
locals {
policy_files = flatten([
for dir, path in local.policy_directories : [
for policy in fileset(path, "*.hcl") : {
name = trim(replace(policy, ".hcl", ""), "/")
path = "${path}/${policy}"
}
]
])
}
# Define vault policies for all sets
resource "vault_policy" "policies" {
for_each = { for policy in local.policy_files : policy.name => policy }
name = each.value.name
policy = file(each.value.path)
}

View File

@ -0,0 +1,9 @@
path "pki_int/issue/*" {
capabilities = ["create", "update", "read"]
}
path "pki_int/renew/*" {
capabilities = ["update"]
}
path "pki_int/cert/*" {
capabilities = ["read"]
}

View File

@ -0,0 +1,7 @@
path "rundeck/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "rundeck/metadata/*" {
capabilities = ["list"]
}

View File

@ -0,0 +1,3 @@
path "ssh-host-signer/sign/hostrole" {
capabilities = ["create", "update"]
}

View File

@ -0,0 +1,3 @@
path "ssh-host-signer/sign/hostrole" {
capabilities = ["create", "update"]
}

View File

@ -0,0 +1,3 @@
path "sshca/sign/host" {
capabilities = ["create", "update"]
}

View File

@ -0,0 +1,3 @@
path "sshca/sign/user" {
capabilities = ["create", "update"]
}

View File

@ -0,0 +1,15 @@
resource "vault_pki_secret_backend_role" "servers_default" {
backend = "pki_int"
name = "servers_default"
#issuer_ref = data.vault_pki_secret_backend_issuer.pki_int_issuer.default
allow_ip_sans = true
allowed_domains = ["unkin.net", "*.unkin.net", "localhost"]
allow_subdomains = true
allow_glob_domains = true
allow_bare_domains = true
enforce_hostnames = true
allow_any_name = true
max_ttl = 2160 * 3600
key_bits = 4096
country = ["Australia"]
}

View File

@ -0,0 +1,6 @@
resource "vault_pki_secret_backend_role" "pki_root_2024_servers" {
backend = vault_mount.pki_root.path
name = "2024-servers"
issuer_ref = data.vault_pki_secret_backend_issuer.pki_root_issuer.issuer_ref
allow_any_name = true
}

View File

@ -0,0 +1,11 @@
resource "vault_ssh_secret_backend_role" "hostrole" {
backend = "ssh-host-signer"
name = "hostrole"
key_type = "ca"
algorithm_signer = "rsa-sha2-256"
ttl = 87600 * 3600
allow_host_certificates = true
allowed_domains = "*"
allow_subdomains = true
allow_bare_domains = false
}

12
role_sshca_signhost.tf Normal file
View File

@ -0,0 +1,12 @@
resource "vault_ssh_secret_backend_role" "sshca_signhost" {
backend = vault_mount.sshca.path
name = "sshca_signhost"
key_type = "ca"
algorithm_signer = "rsa-sha2-256"
ttl = 87600 * 3600
allow_host_certificates = true
allow_subdomains = true
allow_bare_domains = false
allowed_domains = "main.unkin.net,consul"
}