diff --git a/terraform/domains/platform/dev/irsa.tf b/terraform/domains/platform/dev/irsa.tf index c3f0c6e..fde0a0c 100644 --- a/terraform/domains/platform/dev/irsa.tf +++ b/terraform/domains/platform/dev/irsa.tf @@ -1,5 +1,5 @@ # irsa.tf -# Responsibility: IRSA roles for platform workloads (ArgoCD image updater, etc.) +# Responsibility: IRSA roles for platform workloads (ArgoCD image updater, QuanvNN, etc.) # Cluster-level IRSA (ESO, Autoscaler) live in _core/shared/dev/iam.tf # ── ArgoCD image updater ─────────────────────────────────────────────────────── @@ -34,3 +34,36 @@ module "irsa_argocd_image_updater" { Component = "argocd-image-updater" } } + +# ── QuanvNN ML pipeline ──────────────────────────────────────────────────────── +# Read-only access to the QuanvNN datasets bucket (see s3.tf). +# Bound to ServiceAccount system:serviceaccount:ml:quanvnn-sa — the SA name is the +# contract between this role and the ml-batch-job Helm chart's ServiceAccount template. + +module "irsa_quanvnn" { + source = "../../../_core/modules/aws/irsa" + + cluster_oidc_issuer_url = local.cluster_oidc_issuer_url + role_name = "${local.cluster_id}-quanvnn-role" + namespace = "ml" + service_account_name = "quanvnn-sa" + + policy_statements = [ + { + effect = "Allow" + actions = ["s3:ListBucket"] + resources = [aws_s3_bucket.quanvnn_datasets.arn] + }, + { + effect = "Allow" + actions = ["s3:GetObject"] + resources = ["${aws_s3_bucket.quanvnn_datasets.arn}/*"] + }, + ] + + tags = { + Environment = var.environment + Component = "quanvnn" + Workload = "ml" + } +} diff --git a/terraform/domains/platform/dev/outputs.tf b/terraform/domains/platform/dev/outputs.tf index cd62251..7d89d88 100644 --- a/terraform/domains/platform/dev/outputs.tf +++ b/terraform/domains/platform/dev/outputs.tf @@ -15,3 +15,18 @@ output "node_group_arns" { description = "Map of node group name → node group ARN" value = { for k, v in module.node_groups : k => v.node_group_arn } } + +output "quanvnn_datasets_bucket_arn" { + description = "ARN of the QuanvNN datasets S3 bucket" + value = aws_s3_bucket.quanvnn_datasets.arn +} + +output "quanvnn_datasets_bucket_name" { + description = "Name of the QuanvNN datasets S3 bucket" + value = aws_s3_bucket.quanvnn_datasets.bucket +} + +output "quanvnn_irsa_role_arn" { + description = "IRSA role ARN for the QuanvNN ServiceAccount (ml/quanvnn-sa) — read-only S3 access" + value = module.irsa_quanvnn.role_arn +} diff --git a/terraform/domains/platform/dev/s3.tf b/terraform/domains/platform/dev/s3.tf new file mode 100644 index 0000000..8e6c0c2 --- /dev/null +++ b/terraform/domains/platform/dev/s3.tf @@ -0,0 +1,68 @@ +# s3.tf +# Responsibility: S3 buckets for ML workloads on the dev environment. +# QuanvNN datasets bucket — read-only access from the ml namespace via IRSA (see irsa.tf). + +# ── QuanvNN datasets bucket ──────────────────────────────────────────────────── +# Holds satellite imagery patches consumed by the QuanvNN training pipeline. +# Read-only from the cluster — uploads happen out-of-band (operator from a workstation). + +resource "aws_s3_bucket" "quanvnn_datasets" { + bucket = "podyourlife-quanvnn-datasets-dev" + force_destroy = false + + tags = { + Component = "quanvnn-datasets" + Workload = "ml" + } +} + +resource "aws_s3_bucket_versioning" "quanvnn_datasets" { + bucket = aws_s3_bucket.quanvnn_datasets.id + + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "quanvnn_datasets" { + bucket = aws_s3_bucket.quanvnn_datasets.id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + bucket_key_enabled = true + } +} + +resource "aws_s3_bucket_public_access_block" "quanvnn_datasets" { + bucket = aws_s3_bucket.quanvnn_datasets.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + +resource "aws_s3_bucket_ownership_controls" "quanvnn_datasets" { + bucket = aws_s3_bucket.quanvnn_datasets.id + + rule { + object_ownership = "BucketOwnerEnforced" + } +} + +resource "aws_s3_bucket_lifecycle_configuration" "quanvnn_datasets" { + bucket = aws_s3_bucket.quanvnn_datasets.id + + rule { + id = "expire-noncurrent-versions" + status = "Enabled" + + filter {} + + noncurrent_version_expiration { + noncurrent_days = 90 + } + } +}