diff --git a/eks-simple/actions/empty_s3_bucket.toml b/eks-simple/actions/empty_s3_bucket.toml new file mode 100644 index 0000000..9c87b38 --- /dev/null +++ b/eks-simple/actions/empty_s3_bucket.toml @@ -0,0 +1,50 @@ +#:schema https://api.nuon.co/v1/general/config-schema?source=action + +name = "empty_s3_bucket" +break_glass_role = "{{.nuon.install.id}}-s3-object-break-glass" +timeout = "10m" + +[[triggers]] +type = "manual" + +[[steps]] +name = "empty S3 bucket before deletion" +inline_contents = """ +#!/usr/bin/env sh +set -e + +echo "Starting S3 bucket cleanup process..." + +# Delete all object versions and delete markers +echo "Deleting all object versions and delete markers..." +aws s3api list-object-versions --bucket "$BUCKET_NAME" \ + --query 'Versions[].{Key:Key,VersionId:VersionId}' \ + --output text | while read key version_id; do + if [ ! -z "$key" ] && [ ! -z "$version_id" ]; then + echo "Deleting object version: $key (version: $version_id)" + aws s3api delete-object --bucket "$BUCKET_NAME" --key "$key" --version-id "$version_id" + fi +done + +# Delete any remaining delete markers +aws s3api list-object-versions --bucket "$BUCKET_NAME" \ + --query 'DeleteMarkers[].{Key:Key,VersionId:VersionId}' \ + --output text | while read key version_id; do + if [ ! -z "$key" ] && [ ! -z "$version_id" ]; then + echo "Deleting delete marker: $key (version: $version_id)" + aws s3api delete-object --bucket "$BUCKET_NAME" --key "$key" --version-id "$version_id" + fi +done + +# Verify bucket is empty +object_count=$(aws s3api list-objects-v2 --bucket "$BUCKET_NAME" --query 'KeyCount' --output text) +if [ "$object_count" = "0" ] || [ "$object_count" = "None" ]; then + echo "✅ S3 bucket '$BUCKET_NAME' is now empty and ready for deletion" +else + echo "❌ Warning: $object_count objects may still remain in bucket" + exit 1 +fi +""" + +[[env_vars]] +BUCKET_NAME = "{{ .nuon.components.my_bucket.outputs.bucket_name }}" \ No newline at end of file diff --git a/eks-simple/break_glass.toml b/eks-simple/break_glass.toml index 907af56..27cca31 100644 --- a/eks-simple/break_glass.toml +++ b/eks-simple/break_glass.toml @@ -24,3 +24,31 @@ contents = """ ] } """ + +[[role]] +name = "{{.nuon.install.id}}-s3-object-break-glass" +description = "Grants S3 object deletion permissions for bucket cleanup during deprovisioning" +display_name = "{{.nuon.install.id}} - S3 Object Operations Break Glass" +permissions_boundary = "" + +[[role.policies]] +name = "s3-object-operations" +contents = """ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:ListBucket", + "s3:DeleteObject", + "s3:DeleteObjectVersion" + ], + "Resource": [ + "arn:aws:s3:::*-nuon-bucket", + "arn:aws:s3:::*-nuon-bucket/*" + ] + } + ] +} +""" diff --git a/eks-simple/components/s3-bucket.toml b/eks-simple/components/s3-bucket.toml new file mode 100644 index 0000000..14767a8 --- /dev/null +++ b/eks-simple/components/s3-bucket.toml @@ -0,0 +1,14 @@ +#:schema https://api.nuon.co/v1/general/config-schema?type=terraform + +name = "my_bucket" +type = "terraform_module" +terraform_version = "1.11.3" + +[public_repo] +repo = "nuonco/example-app-configs" +directory = "eks-simple/src/components/s3-bucket" +branch = "ja/expand-eks-simple" + +[vars] +install_id = "{{ .nuon.install.id }}" +region = "{{ .nuon.install_stack.outputs.region }}" diff --git a/eks-simple/permissions/maintenance.toml b/eks-simple/permissions/maintenance.toml index 328f6a7..40aac94 100644 --- a/eks-simple/permissions/maintenance.toml +++ b/eks-simple/permissions/maintenance.toml @@ -4,9 +4,6 @@ description = "maintenance" display_name = "byoc-nuon maintenance role" permissions_boundary = "./maintenance_boundary.json" -[[policies]] -managed_policy_name = "AdministratorAccess" - # NOTE: the tag in this policy is determined by the rds_cluster_* component config. the format is known ahead of time by # convention. [[policies]] diff --git a/eks-simple/src/components/s3-bucket/main.tf b/eks-simple/src/components/s3-bucket/main.tf new file mode 100644 index 0000000..459f311 --- /dev/null +++ b/eks-simple/src/components/s3-bucket/main.tf @@ -0,0 +1,29 @@ +resource "aws_s3_bucket" "main" { + bucket = "${var.install_id}-nuon-bucket" +} + +resource "aws_s3_bucket_versioning" "main" { + bucket = aws_s3_bucket.main.id + versioning_configuration { + status = "Enabled" + } +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "main" { + bucket = aws_s3_bucket.main.id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "AES256" + } + } +} + +resource "aws_s3_bucket_public_access_block" "main" { + bucket = aws_s3_bucket.main.id + + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} \ No newline at end of file diff --git a/eks-simple/src/components/s3-bucket/outputs.tf b/eks-simple/src/components/s3-bucket/outputs.tf new file mode 100644 index 0000000..5a861b8 --- /dev/null +++ b/eks-simple/src/components/s3-bucket/outputs.tf @@ -0,0 +1,14 @@ +output "bucket_name" { + description = "Name of the S3 bucket" + value = aws_s3_bucket.main.id +} + +output "bucket_arn" { + description = "ARN of the S3 bucket" + value = aws_s3_bucket.main.arn +} + +output "bucket_domain_name" { + description = "Bucket domain name" + value = aws_s3_bucket.main.bucket_domain_name +} \ No newline at end of file diff --git a/eks-simple/src/components/s3-bucket/providers.tf b/eks-simple/src/components/s3-bucket/providers.tf new file mode 100644 index 0000000..5ff54f0 --- /dev/null +++ b/eks-simple/src/components/s3-bucket/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = var.region +} \ No newline at end of file diff --git a/eks-simple/src/components/s3-bucket/variables.tf b/eks-simple/src/components/s3-bucket/variables.tf new file mode 100644 index 0000000..1d40cc3 --- /dev/null +++ b/eks-simple/src/components/s3-bucket/variables.tf @@ -0,0 +1,9 @@ +variable "install_id" { + description = "The install ID for this Nuon installation" + type = string +} + +variable "region" { + description = "The AWS region where resources will be created" + type = string +} \ No newline at end of file diff --git a/eks-simple/src/components/s3-bucket/versions.tf b/eks-simple/src/components/s3-bucket/versions.tf new file mode 100644 index 0000000..1d70a22 --- /dev/null +++ b/eks-simple/src/components/s3-bucket/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} \ No newline at end of file