mirror of
https://github.com/hanzoai/s3.git
synced 2026-10-30 14:59:09 +00:00
The binary is s3 and the product is Hanzo S3; the rest of the tree now says so too. - Environment: WEED_* and SEAWEEDFS_* are S3_*, no aliases. fla9's flag prefix is S3, matching viper's existing "s3" prefix, so the S3_S3_SSE_* names mini.go exports are the ones viper reads (WEED_S3_SSE_KEK was never seen once viper moved to "s3"). - Java and Hadoop: packages, fs.hanzofs.* keys and the hanzofs:// scheme under the hanzofs namespace the protos already declare; classes take a neutral Filer prefix and file names match them again (the earlier pass left Seas3*.java holding Seaweed* classes). Client, hdfs3, examples, s3copier, random_access and the Spark tests compile. - Helm chart: helpers are hanzo.*, values live under global.s3; the chart renders and lints, which it did not before. - Terraform: the s3.service.tftpl reference matches the file; 12/12 render tests pass. Config paths point at /etc/hanzo, which the binary reads. - loadtest.pb.go regenerated from loadtest.proto. - Upstream logo, sponsor images and unreferenced diagrams removed from note/. Kept: NOTICE attribution, LICENSE, the erasure-coding fixture s3/storage/erasure_coding/1.dat (test bytes), and unmaintained/ and third_party/ (vendored). No on-disk format, wire protocol or metadata key changed. Co-authored-by: Hanzo Dev <[email protected]>
137 lines
5.0 KiB
Terraform
137 lines
5.0 KiB
Terraform
# =============================================================================
|
|
# mTLS + JWT generation and secret delivery (active when enable_security=true).
|
|
#
|
|
# Generates the CA + per-component certs + JWT keys with the security submodule,
|
|
# stores them (plus the rendered security.toml / S3 config) in SSM Parameter
|
|
# Store as SecureString, and renders a boot fetch-secrets.sh that pulls them via
|
|
# the instance role. This keeps secrets OUT of cloud-init user_data / IMDS.
|
|
# Secrets still live in Terraform state (TF-generated); prefer Vault PKI for the
|
|
# CA in production.
|
|
# =============================================================================
|
|
|
|
locals {
|
|
all_private_ips = concat(
|
|
[for k, v in var.masters : v.private_ip],
|
|
[for k, v in var.volumes : v.private_ip],
|
|
[for k, v in var.filers : v.private_ip],
|
|
[for k, v in var.s3_nodes : v.private_ip],
|
|
)
|
|
|
|
ssm_prefix = "/s3/${var.name}"
|
|
deliver_s3_config = length(var.s3_nodes) > 0 || var.embedded_s3.enabled
|
|
|
|
# security.toml is identical across nodes; take it from the first master.
|
|
first_master = var.enable_security ? sort(keys(var.masters))[0] : ""
|
|
security_toml_path = "/etc/hanzo/security.toml"
|
|
s3_config_path = "/etc/hanzo/s3_config.json"
|
|
|
|
# Boot fetch entries: cert files + security.toml + (optional) S3 config.
|
|
fetch_entries = var.enable_security ? concat(
|
|
[for m in module.security[0].secret_manifest : { param = "${local.ssm_prefix}/certs/${m.key}", path = m.path, mode = m.mode }],
|
|
[{ param = "${local.ssm_prefix}/security.toml", path = local.security_toml_path, mode = "0600" }],
|
|
local.deliver_s3_config ? [{ param = "${local.ssm_prefix}/s3_config.json", path = local.s3_config_path, mode = "0600" }] : [],
|
|
) : []
|
|
|
|
fetch_script = var.enable_security ? templatefile("${path.module}/templates/fetch-secrets.sh.tftpl", {
|
|
run_as_user = "s3"
|
|
entries = local.fetch_entries
|
|
}) : ""
|
|
|
|
core_security = var.enable_security ? module.security[0].core_security : var.security
|
|
}
|
|
|
|
module "security" {
|
|
count = var.enable_security ? 1 : 0
|
|
source = "../security"
|
|
internal_domain = var.internal_domain
|
|
cert_dir = var.cert_dir
|
|
ip_sans = local.all_private_ips
|
|
}
|
|
|
|
# ---- SSM SecureString parameters -------------------------------------------
|
|
resource "aws_ssm_parameter" "cert" {
|
|
for_each = var.enable_security ? { for m in module.security[0].secret_manifest : m.key => m } : {}
|
|
name = "${local.ssm_prefix}/certs/${each.key}"
|
|
type = "SecureString"
|
|
value = module.security[0].secret_contents[each.key]
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "aws_ssm_parameter" "security_toml" {
|
|
count = var.enable_security ? 1 : 0
|
|
name = "${local.ssm_prefix}/security.toml"
|
|
type = "SecureString"
|
|
value = module.core.secret_files_by_node["master-${local.first_master}"][local.security_toml_path]
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "aws_ssm_parameter" "s3_config" {
|
|
count = var.enable_security && local.deliver_s3_config ? 1 : 0
|
|
name = "${local.ssm_prefix}/s3_config.json"
|
|
type = "SecureString"
|
|
# identical content across s3/filer nodes; render once via the security module's
|
|
# JSON is not available here, so read it back from any node that carries it.
|
|
value = local.s3_config_source
|
|
tags = var.tags
|
|
}
|
|
|
|
locals {
|
|
# Pull the rendered S3 identity JSON from whichever node carries it.
|
|
s3_config_source = !local.deliver_s3_config ? "" : (
|
|
length(var.s3_nodes) > 0 ?
|
|
module.core.secret_files_by_node["s3-${sort(keys(var.s3_nodes))[0]}"][local.s3_config_path] :
|
|
(length(var.filers) > 0 ? module.core.secret_files_by_node["filer-${sort(keys(var.filers))[0]}"][local.s3_config_path] : "")
|
|
)
|
|
}
|
|
|
|
# ---- IAM: instance role allowed to read the SSM params ----------------------
|
|
data "aws_iam_policy_document" "assume" {
|
|
count = var.enable_security ? 1 : 0
|
|
statement {
|
|
actions = ["sts:AssumeRole"]
|
|
principals {
|
|
type = "Service"
|
|
identifiers = ["ec2.amazonaws.com"]
|
|
}
|
|
}
|
|
}
|
|
|
|
data "aws_iam_policy_document" "ssm_read" {
|
|
count = var.enable_security ? 1 : 0
|
|
statement {
|
|
sid = "ReadS3Params"
|
|
actions = ["ssm:GetParameter", "ssm:GetParameters"]
|
|
resources = ["arn:aws:ssm:*:*:parameter${local.ssm_prefix}/*"]
|
|
}
|
|
statement {
|
|
sid = "DecryptSecureStrings"
|
|
actions = ["kms:Decrypt"]
|
|
resources = [var.kms_key_arn] # defaults to "*"; set a CMK ARN in production
|
|
condition {
|
|
test = "StringEquals"
|
|
variable = "kms:ViaService"
|
|
values = ["ssm.*.amazonaws.com"]
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "aws_iam_role" "node" {
|
|
count = var.enable_security ? 1 : 0
|
|
name_prefix = "${var.name}-node-"
|
|
assume_role_policy = data.aws_iam_policy_document.assume[0].json
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "aws_iam_role_policy" "ssm_read" {
|
|
count = var.enable_security ? 1 : 0
|
|
name = "ssm-read"
|
|
role = aws_iam_role.node[0].id
|
|
policy = data.aws_iam_policy_document.ssm_read[0].json
|
|
}
|
|
|
|
resource "aws_iam_instance_profile" "node" {
|
|
count = var.enable_security ? 1 : 0
|
|
name_prefix = "${var.name}-node-"
|
|
role = aws_iam_role.node[0].name
|
|
}
|