From 30f4b54052d3bfc9ac15f4c0cffb761ce6fc2a5f Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Tue, 29 Sep 2026 19:35:07 -0400 Subject: [PATCH] fix(terraform): scope plan object reads and restore on the data volume The plan role only needs object reads for the verification zip. Unpacking a dump in /tmp fills the root volume. --- terraform/hcp_iam.tf | 25 ++++++++++++++++--------- terraform/user_data.sh | 8 +++++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/terraform/hcp_iam.tf b/terraform/hcp_iam.tf index 409d437..ca243ce 100644 --- a/terraform/hcp_iam.tf +++ b/terraform/hcp_iam.tf @@ -605,22 +605,29 @@ data "aws_iam_policy_document" "hcptf_plan_refresh" { "s3:GetBucketWebsite", "s3:GetEncryptionConfiguration", "s3:GetLifecycleConfiguration", - "s3:GetObject", - "s3:GetObjectAcl", - "s3:GetObjectAttributes", - "s3:GetObjectLegalHold", - "s3:GetObjectRetention", - "s3:GetObjectTagging", "s3:GetReplicationConfiguration", "s3:ListBucket", ] resources = [ "arn:aws:s3:::${local.backup_bucket_name}", - "arn:aws:s3:::${local.backup_bucket_name}/*", "arn:aws:s3:::${local.replica_bucket_name}", - "arn:aws:s3:::${local.replica_bucket_name}/*", "arn:aws:s3:::${local.artifacts_bucket_name}", - "arn:aws:s3:::${local.artifacts_bucket_name}/*", + ] + } + + # aws_s3_object refresh calls HeadObject and object metadata reads. Scope + # them to the verification package. Backup and replica objects stay unread. + statement { + sid = "RefreshLambdaPackage" + effect = "Allow" + actions = [ + "s3:GetObject", + "s3:GetObjectAcl", + "s3:GetObjectAttributes", + "s3:GetObjectTagging", + ] + resources = [ + "arn:aws:s3:::${local.artifacts_bucket_name}/functions/forgejo-backup-verification.zip", ] } diff --git a/terraform/user_data.sh b/terraform/user_data.sh index c46f17e..1ad095d 100644 --- a/terraform/user_data.sh +++ b/terraform/user_data.sh @@ -111,9 +111,11 @@ if [ ! -f /var/lib/forgejo/data/forgejo.db ]; then LATEST="$(aws s3 ls "s3://${BACKUP_BUCKET}/${S3_PREFIX}/" --region "${AWS_REGION}" | awk '{print $2}' | sort | tail -1 | tr -d '/')" if [ -n "$LATEST" ]; then FILE="$(aws s3 ls "s3://${BACKUP_BUCKET}/${S3_PREFIX}/${LATEST}/" --region "${AWS_REGION}" | awk '{print $4}' | tail -1)" - RESTORE_DIR="$(mktemp -d)" - aws s3 cp "s3://${BACKUP_BUCKET}/${S3_PREFIX}/${LATEST}/${FILE}" "$RESTORE_DIR/dump.tar.gz" --region "${AWS_REGION}" - tar xzf "$RESTORE_DIR/dump.tar.gz" -C "$RESTORE_DIR" + # The root volume is 20 GB. A dump expands well past that, so unpack on the data volume. + RESTORE_DIR=/var/lib/forgejo/.restore + rm -rf "$RESTORE_DIR" + mkdir -p "$RESTORE_DIR" + aws s3 cp "s3://${BACKUP_BUCKET}/${S3_PREFIX}/${LATEST}/${FILE}" - --region "${AWS_REGION}" --no-progress | tar -xz -C "$RESTORE_DIR" mkdir -p /var/lib/forgejo/data /var/lib/forgejo/custom if [ -d "$RESTORE_DIR/data" ]; then cp -a "$RESTORE_DIR"/data/. /var/lib/forgejo/data/