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:
parent
4bee3b8313
commit
14790f8277
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.terraform
|
||||||
|
.terraform.lock.hcl
|
||||||
|
env
|
||||||
34
README.md
34
README.md
@ -1,3 +1,37 @@
|
|||||||
# terraform-vault
|
# 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
|
||||||
|
```
|
||||||
|
|||||||
14
auth_approle_certmanager.tf
Normal file
14
auth_approle_certmanager.tf
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
9
auth_approle_rundeck-role.tf
Normal file
9
auth_approle_rundeck-role.tf
Normal 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"]
|
||||||
|
}
|
||||||
14
auth_approle_sshsign-host-role.tf
Normal file
14
auth_approle_sshsign-host-role.tf
Normal 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
17
auth_approle_sshsigner.tf
Normal 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
7
auth_backend_approle.tf
Normal 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
13
auth_backend_ldap.tf
Normal 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
15
engine_kv.tf
Normal 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
49
engine_pki_int.tf
Normal 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
39
engine_pki_root.tf
Normal 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
14
engine_rundeck.tf
Normal 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
18
engine_ssh-host-signer.tf
Normal 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
18
engine_sshca.tf
Normal 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
31
main.tf
Normal 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
31
policies.tf
Normal 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)
|
||||||
|
}
|
||||||
|
|
||||||
9
policies/pki_int/certmanager.hcl
Normal file
9
policies/pki_int/certmanager.hcl
Normal 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"]
|
||||||
|
}
|
||||||
7
policies/rundeck/rundeck.hcl
Normal file
7
policies/rundeck/rundeck.hcl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
path "rundeck/data/*" {
|
||||||
|
capabilities = ["create", "read", "update", "delete", "list"]
|
||||||
|
}
|
||||||
|
|
||||||
|
path "rundeck/metadata/*" {
|
||||||
|
capabilities = ["list"]
|
||||||
|
}
|
||||||
3
policies/ssh-host-signer/sshsign-host-policy.hcl
Normal file
3
policies/ssh-host-signer/sshsign-host-policy.hcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
path "ssh-host-signer/sign/hostrole" {
|
||||||
|
capabilities = ["create", "update"]
|
||||||
|
}
|
||||||
3
policies/ssh-host-signer/sshsigner.hcl
Normal file
3
policies/ssh-host-signer/sshsigner.hcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
path "ssh-host-signer/sign/hostrole" {
|
||||||
|
capabilities = ["create", "update"]
|
||||||
|
}
|
||||||
3
policies/sshca/sshca_signhost.hcl
Normal file
3
policies/sshca/sshca_signhost.hcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
path "sshca/sign/host" {
|
||||||
|
capabilities = ["create", "update"]
|
||||||
|
}
|
||||||
3
policies/sshca/sshca_signuser.hcl
Normal file
3
policies/sshca/sshca_signuser.hcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
path "sshca/sign/user" {
|
||||||
|
capabilities = ["create", "update"]
|
||||||
|
}
|
||||||
15
role_pki_int_servers_default.tf
Normal file
15
role_pki_int_servers_default.tf
Normal 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"]
|
||||||
|
}
|
||||||
6
role_pki_root_2024_servers.tf
Normal file
6
role_pki_root_2024_servers.tf
Normal 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
|
||||||
|
}
|
||||||
11
role_ssh-host-signer_hostrole.tf
Normal file
11
role_ssh-host-signer_hostrole.tf
Normal 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
12
role_sshca_signhost.tf
Normal 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"
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user