file-share/README.md
Adam Moussa 99a0fc9768
Some checks failed
Deploy / deploy (push) Has been cancelled
docs: update README for unmanaged data volume, SFTP, cached AMI (#6)
Storage architecture changed 2026-06-05 (volume imported by ID, not
CFN-managed) — the old Expanding Storage procedure no longer worked.
2026-06-05 15:54:22 -04:00

3.2 KiB

file-share

Personal file share server on AWS — Samba for macOS Finder integration and FileBrowser for web-based file management. Accessible exclusively over the site-to-site VPN.

Architecture

  • EC2 — t4g.small (ARM64, Amazon Linux 2023) in the private subnet. The AMI is cached in the committed cdk.context.json (cachedInContext: true), so deploys never pick up a new AL2023 release implicitly — an AMI change forces instance replacement and must be deliberate (cdk context --reset <ami key> && cdk synth).
  • Samba — SMB file share at /data/share, optimized for macOS (vfs_fruit)
  • FileBrowser — Web UI on port 8080, backed by the same /data/share directory
  • SFTP — password auth for user adam (ForceCommand internal-sftp, same password as SMB); used by Hazel for automated uploads
  • EBS data volume — vol-04d951cccacc435b5, 500 GiB gp3 encrypted, mounted at /data. Unmanaged import: the stack references it by ID (Volume.fromVolumeAttributes + CfnVolumeAttachment), so CloudFormation can attach it but can never create, replace, or delete it — the data survives instance replacement and even stack deletion. UserData waits for the attachment, then mounts the existing filesystem; a blkid guard ensures a disk that already has a filesystem is never formatted.
  • DLM — Daily EBS snapshots at 06:00 UTC, 30-day retention (targets the file-share-backup=true tag, set directly on the volume)
  • SSM — Session Manager for instance access (no SSH key)

History: the data volume was originally an inline blockDevice, which destroyed data on instance replacement (2026-05-27 incident), then a stack-managed standalone volume, which was orphaned when an uncommitted deploy got reverted by CD (2026-06-05 incident). The unmanaged-import design ends that failure class.

Access

Requires VPN connection to the office network (10.10.0.0/16).

Finder (SMB)

  1. Finder > Go > Connect to Server
  2. Enter smb://<private-ip>/files
  3. Authenticate with adam and the password from file-share/smb-password in Secrets Manager

FileBrowser (Web)

Open http://<private-ip>:8080 in a browser.

Secrets

Both stored in AWS Secrets Manager:

Secret Purpose
file-share/smb-password Samba user password
file-share/filebrowser-password FileBrowser admin password

Create these secrets before deploying the stack:

aws secretsmanager create-secret --name file-share/smb-password --secret-string '<password>'
aws secretsmanager create-secret --name file-share/filebrowser-password --secret-string '<password>'

Deploy

npm install
npx cdk deploy

The stack outputs the instance's private IP for SMB and FileBrowser access.

Expanding Storage

The data volume is not managed by CloudFormation (imported by ID), so changing a size in lib/file-share-stack.ts has no effect. Expand it directly — no downtime:

  1. aws ec2 modify-volume --volume-id vol-04d951cccacc435b5 --size <new-GiB>
  2. Wait for the modification to leave modifying: aws ec2 describe-volumes-modifications --volume-ids vol-04d951cccacc435b5
  3. Resize the filesystem via an SSM session:
    sudo resize2fs /dev/nvme1n1   # xvdf surfaces as nvme1n1 on Nitro instances