Skip to content

Commit

Permalink
feat(boundary): add boundary lab
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Morelly authored and FalcoSuessgott committed Feb 5, 2024
1 parent cef44e6 commit 50dda1e
Show file tree
Hide file tree
Showing 40 changed files with 910 additions and 103 deletions.
11 changes: 2 additions & 9 deletions .github/workflows/bootstrap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,8 @@ on:
jobs:
bootstrap:
runs-on: ubuntu-latest

steps:
- uses: hashicorp/setup-terraform@v3

- uses: actions/checkout@v4

- uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
shell: bash
command: make bootstrap
- run: make bootstrap
- run: make teardown
20 changes: 20 additions & 0 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ fmt: ## fmt

.PHONY: bootstrap
bootstrap: deps ## boostrap cluster
source .envrc
source .envrc
terraform init
terraform apply -target=module.boundary -auto-approve
terraform apply -auto-approve

.PHONY: teardown
Expand All @@ -36,8 +37,9 @@ cleanup: ## cleanup
docker rm $(shell docker ps -aq) || true
docker network rm vault || true

rm terraform.tfstate || true
rm terraform.tfstate.backup || true
minikube delete || true

rm terraform.tfstate terraform.tfstate.backup || true

.PHONY: new-lab
new-lab: ## creates a new lab directory
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ Please refer to the [documentation](https://falcosuessgott.github.io/hashicorp-v
* [x] [Vault Agent Injector](https://falcosuessgott.github.io/hashicorp-vault-playground/vai/)
* [x] [CSI Driver](https://falcosuessgott.github.io/hashicorp-vault-playground/csi/)
* [x] [Certmanager](https://falcosuessgott.github.io/hashicorp-vault-playground/cm/)
* [x] [Kubernetes Secret Method](https://falcosuessgott.github.io/hashicorp-vault-playground/boundary/)

### MySQL Dynamic DB Credentials
* [x] [MySQL dynamic DB Credentials](https://falcosuessgott.github.io/hashicorp-vault-playground/databases/)

### Boundary
* [x] [Kubernetes Control Plane Access](https://falcosuessgott.github.io/hashicorp-vault-playground/boundary/)
* [ ] SSH Access

### ToDos
* [ ] Prometheus & Grafana + Vault Metrics
* [ ] Boundary & (kubectl acccess, SSH)
27 changes: 27 additions & 0 deletions boundary-config/files/vault-boundary-k8s.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
path "auth/token/lookup-self" {
capabilities = ["read"]
}

path "auth/token/renew-self" {
capabilities = ["update"]
}

path "auth/token/revoke-self" {
capabilities = ["update"]
}

path "sys/leases/renew" {
capabilities = ["update"]
}

path "sys/leases/revoke" {
capabilities = ["update"]
}

path "sys/capabilities-self" {
capabilities = ["update"]
}

path "minikube/creds/minikube" {
capabilities = ["update"]
}
174 changes: 174 additions & 0 deletions boundary-config/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# The global scope is the outermost scope. There is always a single global scope and it cannot be deleted. The global scope can directly contain: users, groups, auth methods, and organizations.
resource "boundary_scope" "org" {
scope_id = "global"
name = "playground"
description = "Vault Playground"

auto_create_admin_role = false
auto_create_default_role = false
}

# A project is a type of scope used to organize resources such as targets and host catalogs.
resource "boundary_scope" "project" {
name = "minikube"
description = "Local Minikube Cluster"
scope_id = boundary_scope.org.id
auto_create_admin_role = false
auto_create_default_role = false
}

# Auth methods allow users to authenticate within a scope.
resource "boundary_auth_method" "password" {
name = "basic"
description = "Password auth method"
type = "password"
scope_id = boundary_scope.org.id
}

resource "boundary_account_password" "admin" {
name = "admin"
description = "Local Admininistrator Account"
login_name = "admin"
password = "password"
auth_method_id = boundary_auth_method.password.id
}

# Users are entities authorized to access Boundary. Users may be assigned to roles as principals, thus receiving role grants.
resource "boundary_user" "admin" {
name = boundary_account_password.admin.name
account_ids = [boundary_account_password.admin.id]
scope_id = boundary_scope.org.id
}

# Roles are collections of capability grants and the principals (users and groups) assigned to them.
resource "boundary_role" "global_anon_listing" {
name = "Global Anon Listing"
scope_id = boundary_scope.org.id
grant_strings = [
"ids=*;type=auth-method;actions=list,authenticate",
"ids=*;type=scope;actions=list,no-op",
"ids={{.Account.Id}};actions=read,change-password"
]
principal_ids = ["u_anon"]
}

# Roles are collections of capability grants and the principals (users and groups) assigned to them.
resource "boundary_role" "org_anon_listing" {
name = "Org Anon Listing"
scope_id = boundary_scope.org.id
grant_strings = [
"ids=*;type=auth-method;actions=list,authenticate",
"type=scope;actions=list",
"ids={{.Account.Id}};actions=read,change-password"
]
principal_ids = ["u_anon"]
}

# Roles are collections of capability grants and the principals (users and groups) assigned to them.
resource "boundary_role" "org_admin" {
name = "Org Admin"
scope_id = "global"
grant_scope_id = boundary_scope.org.id
grant_strings = [
"ids=*;type=*;actions=*"
]
principal_ids = [boundary_user.admin.id]
}

# Roles are collections of capability grants and the principals (users and groups) assigned to them.
resource "boundary_role" "project_admin" {
name = "Project Admin"
scope_id = boundary_scope.org.id
grant_scope_id = boundary_scope.project.id
grant_strings = [
"ids=*;type=*;actions=*"
]
principal_ids = [boundary_user.admin.id]
}

resource "vault_policy" "boundary" {
name = "boundary-minikube"

policy = file("${path.module}/../files/vault-boundary-k8s.hcl")
}

resource "vault_token" "boundary" {
policies = [vault_policy.boundary.name]

renewable = true
no_parent = true
period = "24h"
}

# A credential store is a collection of credentials and credential libraries.
resource "boundary_credential_store_vault" "this" {
name = "Vault"
description = "Local HashiCorp Vault Cluster"
address = "https://host.docker.internal:443"
token = vault_token.boundary.client_token
scope_id = boundary_scope.project.id

ca_cert = try(file("${path.root}/vault-tls/output/ca.crt"), null)
}

# A credential library is a resource that provides credentials.
resource "boundary_credential_library_vault" "this" {
name = "minikube"
description = "Credentials for Minikube Cluster"
credential_store_id = boundary_credential_store_vault.this.id
path = "minikube/creds/minikube"

http_method = "POST"
http_request_body = jsonencode({
kubernetes_namespace = "default"
})
}

# A host catalog is a collection of hosts and host sets.
resource "boundary_host_catalog_static" "this" {
name = "Minikube"
description = "Minikube Cluster Controlplane"
scope_id = boundary_scope.project.id
}

# A host is a resource that may be accessed by a Boundary target.
resource "boundary_host_static" "minikube" {
name = "minikube"
description = "Minikube API"
address = var.minikube_ip

host_catalog_id = boundary_host_catalog_static.this.id
}

# A host set is a collection of hosts within a host catalog.
resource "boundary_host_set_static" "this" {
host_catalog_id = boundary_host_catalog_static.this.id
host_ids = [boundary_host_static.minikube.id]

}
# A target is a logical collection of host sets which may be used to initiate sessions.
resource "boundary_target" "this" {
name = "minikube"
description = "Minikube Target"
type = "tcp"
default_port = "443"

scope_id = boundary_scope.project.id

host_source_ids = [boundary_host_set_static.this.id]
brokered_credential_source_ids = [boundary_credential_library_vault.this.id]
}

resource "boundary_role" "minikube" {
name = "minikube"
description = "Minikube Role"
scope_id = boundary_scope.org.id

grant_scope_id = boundary_scope.project.id
grant_strings = [
"ids=*;type=target;actions=list,no-op",
"ids=${boundary_target.this.id};actions=authorize-session"
]

principal_ids = [boundary_user.admin.id]
}
3 changes: 3 additions & 0 deletions boundary-config/terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
variable "minikube_ip" {
type = string
}
22 changes: 22 additions & 0 deletions boundary-config/terraform/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
terraform {
required_version = ">= 1.6.0"

required_providers {
vault = {
source = "hashicorp/vault"
version = "3.24.0"
}
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
boundary = {
source = "hashicorp/boundary"
version = "1.1.13"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.25.2"
}
}
}
69 changes: 69 additions & 0 deletions boundary/files/config.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Disable memory lock: https://www.man7.org/linux/man-pages/man2/mlock.2.html
disable_mlock = true

# Controller configuration block
controller {
name = "default"
description = "Boundary Default Controller"

database {
url = "postgresql://postgres:postgres@postgres:5432/postgres?sslmode=disable"
max_open_connections = 5
}
}

worker {
name = "localhost worker"
description = "boundary localhost worker"
public_addr = "127.0.0.1"
}

listener "tcp" {
# Should be the address of the NIC that the controller server will be reached on
address = "0.0.0.0"
purpose = "api"
tls_disable = true
}

listener "tcp" {
# Should be the IP of the NIC that the worker will connect on
address = "boundary"
purpose = "cluster"
tls_disable = true
}

listener "tcp" {
address = "boundary"
purpose = "proxy"
tls_disable = true
}

# Root KMS configuration block: this is the root key for Boundary
kms "transit" {
purpose = "root"
address = "https://host.docker.internal:443"
disable_renewal = "false"
key_name = "boundary_root"
mount_path = "boundary/"
tls_ca_cert = "/opt/tls/ca.crt"
}

# Recovery KMS block: configures the recovery key for Boundary
kms "transit" {
purpose = "recovery"
address = "https://host.docker.internal:443"
disable_renewal = "false"
key_name = "boundary_recovery"
mount_path = "boundary/"
tls_ca_cert = "/opt/tls/ca.crt"
}

# Worker authorization KMS
kms "transit" {
purpose = "worker-auth"
address = "https://host.docker.internal:443"
disable_renewal = "false"
key_name = "boundary_worker"
mount_path = "boundary/"
tls_ca_cert = "/opt/tls/ca.crt"
}
7 changes: 7 additions & 0 deletions boundary/files/vault-policy.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
path "boundary/encrypt/boundary_*" {
capabilities = [ "create", "update" ]
}

path "boundary/decrypt/boundary_*" {
capabilities = [ "create", "update" ]
}
Loading

0 comments on commit 50dda1e

Please sign in to comment.